模板基础
1、模板参数自动推导,如果是已知的参数类型与个数,这调用模板时可以不写类型。
Cout<<max<int>(1,3);可以写为Cout<<max(1,3);这样看起来与普通函数没有区别。
2、最新标准C++11允许使用参数模板默认值,指定默认值后,如下
1 template < typename T0 = float, 2 typename T1, 3 typename T2 = float, 4 typename T3, 5 typename T4> 6 T2 func(T1 v1,T3 v3,T4 v4); 7 8 9 template < typename T0, 10 typename T1, 11 typename T2, 12 typename T3, 13 typename T4> 14 T2 func(T1 v1,T3 v3,T4 v4) 15 { 16 T0 static sv0 = T0(0); 17 T2 static sv2 = T2(0); 18 19 cout<<"\t v1: "<< v1 20 <<"\t v2: "<< v3 21 <<"\t v4: "<< v4 22 <<"\t || sv0: "<< sv0; 23 24 T2 v2 = sv2; 25 26 sv0 -= 1; 27 sv2 -= 1; 28 return v2; 29 }
3、函数模板中的静态局部变量
静态局部变量只有在调用同一个函数时才会操作静态变量,如果参数个数或者类型不同,则不会调用同一个模板函数实例,那局部静态变量也不会改变。
4、函数模板的声明和定义应该放在一个头文件里,这样引用时就不会出现各种问题。但是这样会出现重复引用问题。
5、针对上面出现的重复问题,C++解决方法是:在链接时识别及合并等价的模板实例。这里还要用到命名空间,对于自己写的库,一定要包括到自己的命名空间里,这样就不怕重复问题了。
6、类亦模板,与函数模板相同,但不支持模板实参推导机制,类模板如下
template <typename T = int>//此处可以指定默认值
struct list_node
{
T value;
list_node *next;
};
类模板使用起来和函数模板类似
list_node<int>int_node;
list_node<float>float_node;
如果指定默认值的话,也可以省去类型,但是“<>”不能省略。
list_node<>int_node;
7、C++规定: 在一个类模板内部出现的自身模板名,等价于该模板被调用时所生成的实例。
8、类模板同样可以用于派生生成子模板。
常用的类模板用法:
1 成员函数模板,2 友元函数模板,3 类模板的静态成员
类模板的静态成员,如果有两个文件都生成了含有静态成员变量的类模板的实例,那么在编译时会分配两个静态变量的内存地址,但是在链接时编译器会随机选择一个静态变量的内存地址作为最终的存储空间,从而使不同目标文件中的多个等价模板实例共享一套静态承运存储空间。
9、模板参数类型(typename or class指定的值)
整数模板参数,函数指针模板参数,指针及引用模板参数(局部变量指针或者引用不能用于模板参数),成员函数指针模板参数,模板型模板参数(模板的参数是另一个类模板)。
1 //成员函数指针模板参数 2 3 #include <iostream> 4 using namespace std; 5 6 class some_value; 7 typedef int (some_value::* some_value_mfp )(int);//some_value_mfp是指向一类函数的指针 8 9 template <some_value_mfp func>//func 是一个成员函数指针型模板参数 10 int call(some_value & value,int op) 11 { 12 return (value.*func)(op);//“.*”操作符和“->*”操作符会在这个情况下使用 13 } 14 15 class some_value 16 { 17 int value; 18 public: 19 some_value(int _value) {value = _value;} 20 int add_by(int op) {return value += op;} 21 int sub_by(int op) { return value -= op;} 22 int mul_by(int op) {return value *= op;} 23 }; 24 25 int main() 26 { 27 some_value v0(0); 28 cout<<call<&some_value::add_by>(v0,1)<<endl; 29 cout<<call<&some_value::sub_by>(v0,2)<<endl; 30 cout<<call<&some_value::mul_by>(v0,3)<<endl; 31 getchar(); 32 return 0; 33 }