-
模板形参前面的typename可以换成class。
-
typename是C++晚期才出现的。这里的class与我们常说的类没有关系,只是声明模板参数。不能换成struct。
-
利用域操作符操控全局变量 or 函数。
int value = 1;
int main(){
int value = 1;
::value = 2; //改变的是全局的value
return 0;
}
- 模板会被编译两次,(隐含着模板在编译期实例化)
- 不实例化,只是对 template 程序代码进行语法检查以发现诸如「缺少分号」等等的语法错误。
- 实例化时,编译器检查 template 程序代码中的所有调用是否合法,诸如「未获支持之函数调用」便会在这个阶段被检查出来。
- 这就导致模板的实例化需要模板的原始定义。不能分离编译。
Argument Deduction(实参推导)
- 模板不允许隐式类型转换,
template <typename T>
void max(const T& lhs, const T& rhs){
...
}
max(1,2);
max(1,2.0); //不允许
- 我们的做法是,
- 在传递前将实参强转成相同的参数。
- 显式实例化。
- 假设你真的想传入不同的参数,可以使用多个模板形参。
max(1,static_cast<int>(2.0)); //ok
max<int>(1, 2.0); //ok
Template Parameters
- 当template parameters和call parameters之间没有明显联系,而且编译器无法推导出template parameters 时,你必须明确地在调用时指定template arguments。
template <typename T1, typename T2, typename RT>
RT max(const T1& lhs, const T2& rhs){
...
}
- 模板的自变量类型推导不会推导返回值,而RT跟call parameter又没有直接关系。所以编译器不会推导RT的类型,你必须显式传递RT的类型。
- 但是T1和T2的类型可以自动推导,我们只需要传递RT的类型,却不得不传递三个。简化方式就是,RT作为第一个template parameter。
重载(Overloading)Function Templates
- 每错,你可能会大吃一惊。模板函数也可以用于函数重载。
int max(int a, int b){
return a > b ? a : b;
}
template <class T>
T max(const T& a, const T& b){ //这是模板重载
return a > b ? a : b;
}
- 让你的重载是更显然(存在绝对必要的差异)的重载(参数个数,类型不同),而不是引用和传值之类的隐性重载。
- 让任何重载函数在可能被调用之前声明。