前一节分析了关于template
的使用注意, 本节分析关于template
非类型参数的使用, 非类型参数可能在有些人认为并没有太大作用, 但是既然C++规定有能这样使用就肯定有其意义, 这里就做一个浅析.
非类型参数, 可用在模板中自定义为整型类型, 指针或引用, 不能定义为浮点数等其他类型.
非类型模板参数在编译期间就已经实例化, 所以其模板实参必须是常量表达式.
template<int N>; // N是编译时就确定的常量表达式
template<size_t N, size_t M>; // N,M是编译时就确定的常量表达式
可能就是会觉得没有用, 毕竟使用模板就是要用他的模板参数类型啊, 没有这个那还怎么用. 这里就来先看一个例子.
要求: 实现一个函数返回一个数组的真实大小, 如 : int a[100]; ArrSize(a);返回100
嗯? 讲道理传入函数中a就转换为指针了, 怎么用指针能获取其表示范围? 这里就要用到template
的非类型参数.
template<class T, std::size_t N> // 这里的N是编译时期就知道了, 所以可以加上constexpr关键字
constexpr std::size_t ArrSize(T (&a)[N]) noexcept
{
return N;
}
int a[100]; ArrSize(a);
实现了这个功能后我们就来分析一下.
函数模板通过传入a后会自动推导出 T 的类型为 int, N 的大小为 100, 函数通过引用, 所以传入的是一个a而不是一个指针.
重点在于模板参数N能自动推导传入数组的大小.
同样我们可以将strcmp
做一个封装, 实现一个字符串比较的模板函数.
template<unsigned N, unsigned M>
bool compare(const char (&a)[N], const char (&b)[M])
{
return strcmp(a, b);
}
使用template
的非类型参数可以自动帮我们获取参数的大小, 省去手动传入参数大小的麻烦等问题. 记住 : 非类型模板参数在编译期间就已经实例化, 所以其模板实参必须是常量表达式.