C++模板021-非类型模板参数

C++ 模板的参数不必是类型,也可以是编译时整型常量。例如标准模板库中的 std::array 就接受非类型模板参数用于描述数组的长度: std::array<int, 10>

非类型函数模板参数

例如:

1
2
3
4
template<int val, typename T>
T addVal(T x){
return x + val;
}

该函数模板的实例可以作为可调用对象传入标准模板库中的算法:

1
2
3
transform(nums.begin(), nums.end()
dest.begin(),
addVal<5, int>);

非类型模板参数的限制

只有 常量整数值(包括枚举), 指针(指向对象/函数/成员), 左值引用(指向对象/函数), std::nullptr_t

浮点数和类类型对象不可以做为非类型模板参数

当指针或引用作为模板参数时,其所指向的参数不能是字符串字面量, 临时变量或数据成员以及其他子对像

auto 作为非类型模板参数的类型

自 C++ 17 ,非类型模板参数的类型可以被声明为 auto ,以实现可适用于所有合法类型的模板

例如可以定义:

1
2
3
4
5
6
template<typename T, auto MaxSize>
class Stack {
public:
using size_type = decltype<MaxSize>;
...
}

定义中 Stack 的大小以非类型模板参数的形式传入,且其类型被声明为 auto. 同时,在定义中可以通过 decltype 取出其类型

值得注意的是,也可以将非类型模板参数的类型声明为 decltype(auto), 这样,其类型将允许被推导为引用类型:

1
2
3
4
5
6
7
int i{0};
template<auto I>
class A { };
A<i> a; // I is of type int
template<decltype(auto) J>
class B { };
B<i> b; // J is of type int&