C++ Template 基础篇(一):函数模板
C++ Template 基础篇(一):函数模板
(2025–2026 年最实用、最清晰的入门讲解)
函数模板是 C++ 模板机制的入门级也是最常用的部分。
掌握函数模板后,你就能写出类型无关、复用性极高的代码,这是现代 C++(尤其是泛型编程)的基石。
1. 什么是函数模板?
一句话定义:
函数模板 = “写一次函数,让编译器根据调用时的参数类型自动生成多个具体版本的函数”
换句话说:你只写一份代码,编译器帮你生成 int 版、double 版、string 版、自定义类版…… 所有需要的版本。
2. 最经典的例子:求最大值
传统写法(重复劳动)
intmax(inta,intb){returna>b?a:b;}doublemax(doublea,doubleb){returna>b?a:b;}longlongmax(longlonga,longlongb){returna>b?a:b;}// …… 每种类型都要写一遍,太痛苦用函数模板(一次编写,到处使用)
template<typenameT>// 或 template <class T>(两者等价)Tmax(T a,T b){returna>b?a:b;}使用方式:
intmain(){cout<<max(3,7)<<endl;// 调用 int 版本cout<<max(2.5,1.8)<<endl;// 调用 double 版本cout<<max(100LL,200LL)<<endl;// 调用 long long 版本string s1="apple",s2="banana";cout<<max(s1,s2)<<endl;// 调用 string 版本(按字典序比较)}编译器在编译时会自动为每种调用生成一份具体函数(称为模板实例化)。
3. 模板语法核心关键词
| 写法 | 含义 | 现代推荐写法(C++11+) |
|---|---|---|
template <typename T> | T 是类型参数 | 推荐(最清晰) |
template <class T> | 与上面完全等价 | 历史写法,仍合法 |
template <typename T1, typename T2> | 多个类型参数 | 常见于 map、pair 等 |
template <int N> | 非类型参数(常量) | 后面会讲 |
4. 函数模板的推导规则(最容易出错的地方)
编译器如何决定 T 是什么?
规则总结(优先级从高到低):
- 显式指定类型(最强,强制使用)
max<double>(3,4.5);// 强制 T = double,3 会被隐式转换为 double- 根据实参自动推导(最常见)
max(10,20);→ T=intmax(1.2f,3.4);→ T=float- 常见陷阱:不同类型实参时推导失败
max(10,3.14);// 错误!编译器不知道 T 应该是 int 还是 double解决办法(三种任选):
// 方案1:显式指定max<double>(10,3.14);// 方案2:统一类型max(10.0,3.14);// 方案3:重载或使用模板重载(后面会讲)5. 模板函数的重载与特化
模板函数也可以和普通函数、其他模板函数一起重载。
// 普通函数(优先级最高)intmax(inta,intb){cout<<"调用普通函数\n";returna>b?a:b;}// 模板函数template<typenameT>Tmax(T a,T b){cout<<"调用模板\n";returna>b?a:b;}// 调用max(5,3);// → 调用普通函数(非模板函数优先)max(5.0,3.0);// → 调用模板(没有匹配的普通函数)模板特化(针对特定类型写特殊版本)
// 针对 const char* 的特化版本(字符串比较用 strcmp)template<>constchar*max<constchar*>(constchar*a,constchar*b){returnstrcmp(a,b)>0?a:b;}6. 非类型模板参数(C++11 前就存在,很实用)
template<intN>voidprint_fixed_size_array(int(&arr)[N]){for(inti=0;i<N;++i){cout<<arr[i]<<" ";}}intmain(){inta[5]={1,2,3,4,5};print_fixed_size_array(a);// N 自动推导为 5}7. 2026 年写函数模板的现代最佳实践
// 推荐写法(C++20 概念 + auto 参数)#include<concepts>// 要求 T 支持 < 运算符template<typenameT>requiresstd::totally_ordered<T>// C++20 概念约束Tmy_max(T a,T b){returna<b?b:a;}// 更现代:C++20 缩写语法automy_max(std::totally_orderedautoa,std::totally_orderedautob){returna<b?b:a;}8. 小结:函数模板一句话记住
函数模板让你写一份代码,编译器自动生成 N 份类型特化的函数。
核心口诀:
- 用
template <typename T>开头 - T 代表“任意类型”
- 编译器在调用时自动推导或显式指定 T
- 重复参数类型自动去重,优先匹配普通函数
- 想限制类型 → 用 C++20 概念(requires)
下一篇文章可以继续讲:
- 类模板(class template)
- 模板特化 & 偏特化
- 变参模板(variadic template)
- C++20 概念(concepts)实战
你想现在就继续看“类模板”还是先做几个函数模板练习题?或者有具体的使用场景(排序、比较、打印容器等)想看示例?告诉我,我立刻写给你。
