如果对模板或者C++标准感兴趣的开发者们相信都不会对变量模板感到陌生,我们今天就讲一讲变量模板
从C++14 开始,变量也可以被某种类型参数化。称为变量模板。
例如可以通过下面的代码定义pi,但是参数化了其类型:
template<typename T=int>//我们写作默认int T pi{};//初始化列表 为0 int main() { std::cout.precision(16); pi<int> = 20;//pi<>=20;效果一样 std::cout << pi<int> << std::endl; //20 pi<double> = 3.14159265358; std::cout << pi<double> << std::endl;//3.14159265358 std::cout << pi<float> << std::endl;//0 return 0; }
注意,和其它几种模板类似,这个定义不要出现在函数内部或者块作用域内部。
那么我们这样使用它,它是什么?我们没有创建局部变量,注意,它不是局部变量,这是一个全局变量,我们这个过程是实例化了一个全局变量。
而且我们必须显性声明模板参数。
我们讲讲它的一些用处
打个比方,如果要使用一个类的静态数据,必须像下面这样调用
#include<iostream> #include<string> template<typename T> class MyClass { public: static constexpr int max = 1000; }; int main(){ MyClass<int>::max; }
得加上作用域解析运算符,但是,有了变量模板之后,我们可以
#include<iostream> #include<string> template<typename T> class MyClass { public: static constexpr int max = 1000; }; //这意味着对于一个标准库的类: template<typename T> int myMax = MyClass<T>::max; namespace std { template<typename T> class numeric_limits { public: static constexpr bool is_signed = false; }; } //可以定义: template<typename T> constexpr bool isSigned = std::numeric_limits<T>::is_signed; int main(){ //应用工程师就可以使用下面这样的代码: auto i = myMax<std::string>; std::cout << i << std::endl; //而不是: //auto i = MyClass<std::string>::max; //std::cout << i << std::endl; system("pause"); return 0; }
熟悉标准库的开发者,对于#include<type_traits>不会陌生,我们举两个简单的例子
template<typename T> auto func(T& a) { std::cout << typeid(a).name() << " "; if (std::is_array_v<T>) { std::cout << "是数组" << std::endl; } else std::cout << "不是数组" << std::endl; } template<typename T> auto func2(T& v) { std::cout << typeid(v).name() << " "; if (std::is_const_v<T>) { std::cout << "是const" << std::endl; } else std::cout << "不是const" << std::endl; }
这第一种相当于使用了变量模板,也有不使用的写法
template<typename T> auto func(T& a) { std::cout << typeid(a).name() << " "; if (std::is_array<T>::value) { std::cout << "是数组" << std::endl; } else std::cout << "不是数组" << std::endl; } template<typename T> auto func2(T& v) { std::cout << typeid(v).name() << " "; if (std::is_const<T>::value) { std::cout << "是const" << std::endl; } else std::cout << "不是const" << std::endl; }
发现了吗?第二种相当于我们一开始介绍的使用作用域解析运算符来取出的值,标准委员会保留老式的写法,但是也更新形式的方法,大家理解即可。
仅供参考,如有错误还请指正
C++14变量模板
于 2022-05-09 13:20:55 首次发布