news 2026/10/3 2:31:55

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【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函数模板的实例化

函数模板实例化是指编译器根据模板实参,把“模板”变成“具体函数的过程。

隐式实例化-调用时由编译器自动推导模板参数的类型并生成函数

template<typename 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);
  • 或者用显式实例化,这样写:add<int>(a1,b2);

1.5非模板函数与模板函数重载:

(1)一个非模板函数和一同名的模板函数可以同时存在,并且该函数模板还会实例化出这个非模板函数,比如:

template<typename T> void print(T x) // 模板函数 { //... } void print(int x) // 非模板函数 { //... }

函数模板 print( T ) 在 T = int 时,会实例化出一个函数: void print<int>(inx) {...} ,这个函数可以和 void print(int x) {...} 同时存在。

(2)模板函数和非模板函数同时存在时,会优先调用非模板函数,比如:

template<typename 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 = add<int>(1, 2); // 调用模板 return 0; }

2.类模板:

2.1 类模板的格式和实例化

template<typename T> class Stack { vector<T> data; // 用 vector 存数据 public: // 入栈 void push(const T& val) { data.push_back(val); } // ... }; int main() { //Stack s1; // err //Stack s2; // err // 存 int 的栈 Stack<int> s1; // 存 double 的栈 Stack<double> s2; return 0; }

注意:类模板必须显式实例化


模板不建议声明和定义分离

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/3 2:30:56

Go 内存对齐与数据结构性能:字段顺序影响 50% 内存占用

Go 内存对齐与数据结构性能&#xff1a;字段顺序影响 50% 内存占用struct 字段顺序变了&#xff0c;内存占用也变了。写 Go 服务必须懂内存对齐规则&#xff0c;能让数据结构更紧凑。一、对齐基础 CPU 读内存一般按 8 字节对齐。如果 struct 内部字段顺序错乱&#xff0c;编译时…

作者头像 李华
网站建设 2026/10/3 2:30:53

蓝牙芯片驱动开发-第6章第5题-如何确保ACL数据包的正确识别与处理

蓝牙面试题解析:如何确保 ACL 数据包的正确识别与处理? 难度:⭐⭐⭐⭐ 较难 | 场景:社招二面/三面、蓝牙驱动开发 | 高频:🔥🔥🔥🔥 标准答案 ACL 数据包的识别与处理通过 类型标识 + 句柄匹配 + 完整性校验 + 缓冲管理 四层保障: ① 包类型识别(H4 传输层) …

作者头像 李华