深入解析C++非类型模板参数

目录

一、模板参数分类

二、非类型模板参数的应用

三、使用示例

四、非类型模板参数的限制

五、实际应用示例

六、非类型模板参数的默认值

1、基本语法

2、实际示例

[1. 静态数组类设置默认大小](#1. 静态数组类设置默认大小)

[2. 使用示例](#2. 使用示例)

3、注意事项


一、模板参数分类

模板参数可分为两种主要类型:

  1. 类型形参出现在模板参数列表中,跟在classtypename关键字之后的参数类型名称

  2. 非类型形参使用一个常量作为类或函数模板的参数,在模板中可将该参数当作常量使用


二、非类型模板参数的应用

非类型模板参数常用于需要编译期确定值的场景,例如实现静态数组类:

cpp 复制代码
template<class T, size_t N> // N是非类型模板参数
class StaticArray {
public:
    size_t arraysize() const {
        return N;
    }
    
    T& operator[](size_t index) {
        return _array[index];
    }
    
    const T& operator[](size_t index) const {
        return _array[index];
    }
    
private:
    T _array[N]; // 利用非类型模板参数指定静态数组的大小
};

三、使用示例

cpp 复制代码
int main() {
    StaticArray<int, 10> a1;    // 定义大小为10的整型静态数组
    cout << a1.arraysize() << endl; // 输出: 10
    
    StaticArray<double, 100> a2; // 定义大小为100的双精度静态数组
    cout << a2.arraysize() << endl; // 输出: 100
    
    return 0;
}

四、非类型模板参数的限制

  1. 允许的类型

    • 只允许使用整型家族(包括整数、字符、布尔等)

    • 指针和引用在特定情况下也允许

  2. 不允许的类型:浮点数、类对象、字符串字面量

  3. 编译期要求

    • 非类型模板参数必须在编译期就能确定结果

    • 因为编译器需要在编译阶段根据这些参数生成对应的类或函数


五、实际应用示例

标准库中的std::array就是一个使用非类型模板参数的典型例子:

cpp 复制代码
namespace bite {
    // 定义一个模板类型的静态数组
    template<class T, size_t N = 10> // 默认大小为10
    class array {
    public:
        T& operator[](size_t index) { return _array[index]; }
        const T& operator[](size_t index) const { return _array[index]; }
        
        size_t size() const { return N; } // 直接返回模板参数N
        bool empty() const { return N == 0; }
        
    private:
        T _array[N];
    };
}

非类型模板参数为C++模板编程提供了更多灵活性,特别是在需要编译期常量的场景中非常有用。


六、非类型模板参数的默认值

非类型模板参数可以设置默认值,这与类型模板参数设置默认值的语法规则相同。

1、基本语法

cpp 复制代码
template <class T, size_t N = 默认值>  // 为非类型参数N设置默认值
class ClassName {
    // 类定义
};

2、实际示例

1. 静态数组类设置默认大小

cpp 复制代码
template <class T, size_t N = 10>  // 默认数组大小为10
class StaticArray {
public:
    size_t size() const { return N; }
    // ... 其他成员函数
private:
    T _array[N];
};

2. 使用示例

cpp 复制代码
int main() {
    StaticArray<int> a1;      // 使用默认大小10
    StaticArray<double, 20> a2; // 显式指定大小20
    
    cout << a1.size() << endl; // 输出: 10
    cout << a2.size() << endl; // 输出: 20
    
    return 0;
}

3、注意事项

  1. 默认参数规则

    • 与函数默认参数类似,从右向左设置默认值

    • 如果某个模板参数有默认值,它右边的所有参数都必须有默认值

  2. 正确示例

    cpp 复制代码
    template <class T = int, size_t N = 10>  // 正确
    class A {};
  3. 错误示例

    cpp 复制代码
    template <class T = int, size_t N>  // 错误:N没有默认值
    class B {};

这种技术广泛用于需要编译期确定大小的容器类,是模板元编程中的重要技术之一。

相关推荐
C4程序员13 分钟前
北京JAVA基础面试30天打卡14
java·开发语言·面试
黑客影儿40 分钟前
Go特有的安全漏洞及渗透测试利用方法(通俗易懂)
开发语言·后端·安全·web安全·网络安全·golang·系统安全
君鼎1 小时前
Effective C++ 条款55:熟悉Boost库
c++
你好,我叫C小白1 小时前
C语言 常量,数据类型
c语言·开发语言·数据类型·常量
小红帽2.02 小时前
从ioutil到os:Golang在线客服聊天系统文件读取的迁移实践
服务器·开发语言·golang
Zafir20243 小时前
Qt实现TabWidget通过addTab函数添加的页,页内控件自适应窗口大小
开发语言·c++·qt·ui
多吃蔬菜!!!3 小时前
vscode 搭建C/C++开发环境搭建(linux)
linux·c语言·c++
小指纹5 小时前
河南萌新联赛2025第(六)场:郑州大学
java·开发语言·数据结构·c++·算法
岁忧5 小时前
(nice!!!)(LeetCode 每日一题) 1277. 统计全为 1 的正方形子矩阵 (动态规划)
java·c++·算法·leetcode·矩阵·go·动态规划