函数模板类型推导取决于形参声明形式:t推导为裸类型,t&保留cv限定但忽略引用性,const t&使t不含const,t&&按值/引用折叠规则推导;多参数需统一t,否则编译失败。

函数模板类型推导看形参写法,不是只看实参
编译器推导 T 时,不单看传进去的变量是什么类型,更关键的是看模板形参的声明形式:T、T&、const T&、T&& —— 每种写法规则完全不同。同一实参(比如 const int& rx)在不同形参下,推导出的 T 可能是 int、const int 或 const int&。
-
T param(按值传递):丢掉引用、丢掉const/volatile,T总是“裸类型”。例如func(cx)中cx是const int,但T推导为int -
T& param(左值引用):保留const/volatile,但忽略实参本身的引用性。例如func(rx)(rx是const int&),T推导为const int,param类型是const int& -
const T& param(常量左值引用):const被“外提”,T不再带const。无论传int、const int还是const int&,T都是int -
T&& param(万能引用):左值传入 →T推导为XXX&;右值传入 →T推导为XXX。这是唯一能触发引用折叠的场景
多参数模板必须能统一推导出一致的T
当函数模板有多个 T 参数时,所有实参必须能推导出同一个 T,否则编译失败。这不是“取交集”,而是“强制一致”。
-
template<typename t> void f(T a, T b);</typename>——f(1, 3.14)错误:一个推int,一个推double,无法统一 -
template<typename t1 typename t2> void f(T1 a, T2 b);</typename>—— 没问题,各自独立推导,T1=int、T2=double - 想支持混合类型又保持单模板参数?得用
auto(C++14 起)或std::common_type手动约束,不能靠默认推导
显式指定类型会跳过推导,但可能引发隐式转换
写成 func<int>(3.14)</int> 就强制让 T 是 int,编译器不再看实参类型。这时候实参会被尝试转换,可能静默截断或触发用户定义转换。
template<typename t> void f(T x) { std::cout </typename>-
f(3.14);→ 推导T=double,输出8 -
f<int>(3.14);</int>→ 强制T=int,3.14被转成3,输出4 - 尤其注意指针/引用场景:
f<const char>(std::string("hi"))</const>会尝试调用std::string::c_str(),但若没这个转换操作符就直接报错
const 和引用修饰符到底保不保留,取决于形参是否“绑定到顶层限定符”
最易混淆的点:为什么 T& 保留 const,而 const T& 却不?关键在“谁承担 const 性”。
-
template<typename t> void f(T& param)</typename>:param是引用,它的 const 性由T决定,所以const int&实参 →T=const int -
template<typename t> void f(const T& param)</typename>:const是写死的顶层限定符,T必须是“可被 const 修饰的类型”,所以const不进T,只加在T&外面 - 验证方式:用
boost::typeindex::type_id_with_cvr<t>().pretty_name()</t>打印真实类型,比靠猜可靠得多
& 或 const,推导结果就可能完全不同。C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











