使用template
定义函数模板时,使用 template
前缀” />
函数模板的基本结构
一个最简单的函数模板看起来像这样:
前缀” />
template<typename T> T max(T a, T b) { return (a > b) ? a : b; }
- template
:这是模板声明前缀,表示这是一个模板函数。 - T 是一个类型参数,在调用函数时由编译器自动推导或显式指定。
- 函数体中的逻辑和普通函数一样,只是用 T 替代了具体类型。
你可以用这个函数比较 int、double、甚至自定义类型的值(只要支持 > 运算符)。
模板关键字 typename 的含义
在 template
前缀” />
template<class T> T max(T a, T b);
其实这两种写法在函数模板中是等价的,都可以使用。不过从语义上讲,typename 更准确一些,因为它明确表示这是一个通用类型,而不仅仅是类类型。
使用函数模板的几种方式
-
自动类型推导
在调用模板函数时,如果参数类型能被明确推导出来,可以直接省略类型:int a = 3, b = 5; int result = max(a, b); // 编译器自动推导为 max<int>
-
显式指定类型
如果你想强制使用某种类型,或者无法通过参数推导出类型,可以显式指定:double result = max<double>(3.0, 5);
-
多个模板参数
函数模板也可以有多个类型参数,比如:template<typename T, typename U> void printPair(T a, U b) { std::cout << a << " and " << b << std::endl; }
注意事项与常见问题
-
类型必须兼容
如果传入的类型不支持函数内部的操作(比如没有重载 > 运算符),编译会失败。 -
模板不能跨文件分离声明和定义
函数模板的定义(包括函数体)通常必须放在头文件中,否则链接时可能找不到实现。 -
避免重复实例化
编译器会根据不同的类型生成不同的函数版本,这可能导致代码膨胀,尤其在大型项目中要注意控制模板使用的范围。
基本上就这些。掌握 template