深入解析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 {};

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

相关推荐
Yupureki41 分钟前
从零开始的C++学习生活 16:C++11新特性全解析
c语言·数据结构·c++·学习·visual studio
紫荆鱼1 小时前
设计模式-迭代器模式(Iterator)
c++·后端·设计模式·迭代器模式
汤姆yu2 小时前
基于python的化妆品销售分析系统
开发语言·python·化妆品销售分析
ScilogyHunter2 小时前
C语言标准库完全指南
c语言·开发语言
sali-tec2 小时前
C# 基于halcon的视觉工作流-章52-生成标定板
开发语言·图像处理·人工智能·算法·计算机视觉
应茶茶2 小时前
C++11 核心新特性:从语法重构到工程化实践
java·开发语言·c++
程子的小段2 小时前
C 语言实例 - 字符串复制
c语言·开发语言
-森屿安年-3 小时前
STL 容器:stack
开发语言·c++
歪歪1003 小时前
C#如何在数据可视化工具中进行数据筛选?
开发语言·前端·信息可视化·前端框架·c#·visual studio
charlee443 小时前
最小二乘问题详解6:梯度下降法
c++·梯度下降·雅可比矩阵·非线性最小二乘·参数拟合