ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

【C++】函数模板和类模板

【C++】函数模板和类模板 1.函数模板1.1 函数模板的概念写一次逻辑让编译器针对不同类型/值生成具体代码。模板本身不是函数或类实例化后才产生真正的代码。1.2函数模板格式比如:template typename T T add(T a, T b) { return a b; }add 本身不是函数而是函数模板。调用 add(1,2) 时编译器生成 int 版本的函数调用 add(1.0 , 2.0) 时生成 double 版本的函数。typename 也能写成 class但是不能写成struct多个模板参数template typename T1, typename T2 void printPair(T1 a, T2 b) { std::cout a , b \n; }1.3函数模板的原理编译器看到函数模板定义 -根据实参推导模板参数确定 T 的类型-生成对应具体函数- 对该具体函数进行类型检查和代码生成。例如template typename T T myMax(T a, T b) { return a b ? a : b; } int main() { myMax(1, 2); // 生成 int myMax(int, int) myMax(1.5, 2.5); // 生成 double myMax(double, double) }1.4函数模板的实例化函数模板实例化是指编译器根据模板实参把“模板”变成“具体函数的过程。隐式实例化-调用时由编译器自动推导模板参数的类型并生成函数templatetypename T T add(const T a,const T b) { return a b; } int main() { int a1 1, a2 2; double b1 1.1, b2 2.2; add(a1, a2);// 调用时会隐式实例化 add(b1, b2); return 0; }显式实例化-手动写出模板形参上面的代码如果在调用时写add(a1,b2); 就会报错因为第一个参数传给模板识别出类型为int,但第二个参数类型却是double而模板函数不允许自动类型转换所以编译器最终无法确定T到底是int 还是double 类型。要想解决这个问题可以手动强制类型转换如 add(a1,(int)b2)或者用显式实例化这样写addint(a1,b2);1.5非模板函数与模板函数重载1一个非模板函数和一同名的模板函数可以同时存在并且该函数模板还会实例化出这个非模板函数比如templatetypename T void print(T x) // 模板函数 { //... } void print(int x) // 非模板函数 { //... }函数模板 print( T ) 在 T int 时会实例化出一个函数 void printint(inx) {...} 这个函数可以和 void print(int x) {...} 同时存在。2模板函数和非模板函数同时存在时会优先调用非模板函数比如templatetypename T // 模板 T add(const T a, const T b) { return a b; } int add(const int a, const int b) // 非模板 { return a b; }如果传的参数都是整型会优先调用 int add 函数但如果就是想调用模板可以用显式实例化比如int main() { //int r1 add(1,2); // 调用非模板的函数 int r2 addint(1, 2); // 调用模板 return 0; }2.类模板:2.1 类模板的格式和实例化templatetypename T class Stack { vectorT data; // 用 vector 存数据 public: // 入栈 void push(const T val) { data.push_back(val); } // ... }; int main() { //Stack s1; // err //Stack s2; // err // 存 int 的栈 Stackint s1; // 存 double 的栈 Stackdouble s2; return 0; }注意类模板必须显式实例化模板不建议声明和定义分离
返回列表