C++: 模板参数的自动推导
2018-11-19 本文已影响9人
赵伯舟
简单例子
template <typename T>
T Add(T t1, T t2)
{
return t1 + t2;
}
int main()
{
std::cout << Add(0, 1) << std::endl; //works
std::cout << Add(0.1, 1.0) << std::endl; //works
std::cout << Add("Hello", " World") << std::endl; //error
std::cout << Add(0.1, 3) << std::endl; //error
}
上述代码中,Add(0, 1)
自动推导出模板T为整型,而Add(0.1, 3)
报错,这是因为其推导出参数是两个类型:浮点数和整型,而函数声明中只有一个类型。而Add("Hello", " World")
报错则是因为其推导出其类型为const char *
,无法进行相加操作。
C++中的模板参数自动推导有以下原则:
- 编译器只根据函数调用时给出的实参列表来推导模板参数值,与函数参数类型无光的模板参数其值无法推导
- 与函数返回值相关的模板参数其值也无法推导。原因是C++存在内建的内动类型转化机制,函数返回值的类型可能发生隐式类型转换
- 所有可推导模板参数必须是连续位于模板参数列表尾部,中间不能有不可推导的模板参数
复杂例子
template <typename T0, typename T1, typename T2, typename T3, typename T4>
T2 func(T1 v1, T3 v2, T4 v3)
{
T0 static t0 = T0(0);
T2 t2 = v1 + v2 + v3;
return t2;
};
int main()
{
std::cout << func<double, int, int>(0, 1, 1.2) << std::endl;
}
上述func
中用到多个模板参数,其中T0
和函数实参无关,所以必须指定,而T2
和返回值相关,所以也必须指定,又因为模板的形参和实参是通过位置来进行关联的,所以T1
夹在T0
和T1
之间,其也需要显式指定。T3
和T4
则可以从实参列表中推导出来