如果对模板或者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;
}
发现了吗?第二种相当于我们一开始介绍的使用作用域解析运算符来取出的值,标准委员会保留老式的写法,但是也更新形式的方法,大家理解即可。
仅供参考,如有错误还请指正