模板函数template t max(t a, t b) { return a > b ? a : b; }可统一处理int和string等支持>的类型,调用时自动推导t,无需重载或重复编码。

怎么写一个能处理 int 和 string 的 max 函数
直接用模板函数,别写重载。C++ 模板不是“高级技巧”,而是解决重复代码的第一选择。
常见错误是照着普通函数抄一遍类型,比如先写 int max(int a, int b),再复制粘贴改成 string max(string a, string b)——这样改 5 个类型就得维护 5 份逻辑,一加个 const& 就全漏改。
- 用
template<typename t></typename>声明泛型,T是占位符,编译器会按实参推导 - 函数体里只用
T,别硬写int或std::string - 必须确保
T支持>操作符,否则编译失败(比如传入自定义类且没重载operator>)
template<typename t>
T max(T a, T b) {
return a > b ? a : b;
}</typename>
调用时完全不用指定 T:max(3, 7) 推出 T=int,max("hello", "world") 推出 T=const char*(注意:这不是 std::string,比较的是指针值)
为什么 std::vector<t></t> 不能直接当模板参数传给函数
因为 std::vector<t></t> 是类型模板,不是具体类型;函数参数要的是实例化后的类型,比如 std::vector<int></int>。
常见错误是写 void foo(std::vector<t> v)</t> 却没声明 template<typename t></typename>,编译器根本不知道 T 是啥。
- 要么显式写全特化类型:
void foo(std::vector<int> v)</int> - 要么把整个函数做成模板:
template<typename t> void foo(std::vector<t> v)</t></typename> - 更常用的是用
const std::vector<t>&</t>避免拷贝,尤其对大对象
注意:如果函数只读数据,用 std::span<const t></const>(C++20)或 const std::vector<t>&</t> 更通用,不绑定容器实现。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
auto 和模板参数 T 在函数返回值里怎么选
想返回和参数运算结果一致的类型?别盲目用 auto。它靠返回语句推导,而模板 T 是靠调用实参推导——两者源头不同,行为可能不一致。
典型坑:传入 short 和 int 调用 template<typename t> auto add(T a, T b) { return a + b; }</typename>,a + b 是 int(整型提升),但模板要求两个参数都是同一种 T,所以 add(short(1), int(2)) 根本编译不过。
- 坚持“参数决定类型”原则:用
template<typename t></typename>+ 明确返回T,强制调用者统一类型 - 需要自动匹配混合类型?上
decltype:template<typename t typename u> auto add(T a, U b) -> decltype(a + b)</typename> -
auto返回值适合 lambda 或简单内联场景,不适合接口稳定的函数
模板函数定义为什么不能放在 .cpp 里
链接时报 undefined reference to 'max<int>(int, int)'</int>?因为你把模板定义放 .cpp 了。模板不是普通函数,它没有“目标码”,只有被调用时才生成具体版本。
编译器在编译调用点(比如 main.cpp)时,需要看到完整的模板定义才能实例化。如果只在头文件里声明 template<typename t> T max(T,T);</typename>,定义却在 .cpp 里,main.cpp 根本看不到怎么生成 max<int></int>。
- 所有模板声明和定义都得放在头文件(.h 或 .hpp)里
- 不想暴露实现?用显式实例化:在 .cpp 里写
template int max<int>(int, int);</int>,但只适用于你确定的少数类型 - C++20 模块(modules)能解决这问题,但目前主流项目仍靠头文件组织
最易被忽略的一点:模板参数名在不同头文件里冲突不会报错,但含义错位会导致静默错误——比如一个头文件用 T 表示元素类型,另一个用 T 表示分配器,合在一起用就崩。起名还是加前缀稳当,比如 ElementType。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!









