模板参数推导结合通用引用和引用折叠实现完美转发,如std::make_unique通过T&&推导实参类型,依据引用折叠规则保持值类别,使std::forward能原样转发参数给目标函数。

在C++中,模板参数推导和引用折叠是理解泛型编程(尤其是完美转发和通用引用)的关键机制。它们共同支撑了现代C++中高效、灵活的接口设计,比如 std::make_unique、std::forward 和各种工厂函数。
模板参数推导规则(Template Argument Deduction)
当编译器根据函数调用的实参自动确定模板参数类型时,就发生了模板参数推导。最常见的场景是函数模板:
template<typename T>
void func(T param);
<p>func(42); // T 被推导为 int,param 类型是 int
func("hello"); // T 被推导为 const char[6],param 是 const char*</p>登录后复制
但推导行为会因参数类型的不同而变化。以下是几种常见情况:
- 值类型(T param):会忽略顶层 const 和引用,数组和函数会退化为指针。
- 引用类型(T& param):保留底层 const,不退化数组或函数类型。
- 通用引用(T&& param):这是最关键的场景,支持引用折叠,并允许实现完美转发。
通用引用(Universal References)与右值引用(Rvalue References)
Scott Meyers 提出“通用引用”这个术语来描述出现在模板和 auto 声明中的 T&&。它既可以绑定左值,也可以绑定右值,具体类型由初始化表达式决定:
立即学习“C++免费学习笔记(深入)”;
template<typename T>
void func(T&& param) { /* param 是通用引用 */ }
<p>int x = 42;
func(x); // x 是左值 → T 被推导为 int&,param 类型是 int&&(但实际是左值引用)
func(42); // 42 是右值 → T 被推导为 int,param 类型是 int&&</p>登录后复制
注意:只有在模板参数推导发生时,T&& 才是通用引用。像 void func(int&&) 这样的明确右值引用就不是通用引用。
引用折叠规则(Reference Collapsing Rules)
引用折叠是 C++11 引入的核心规则,用于解决“引用的引用”这种非法语法。规则如下:
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。
还木有评论哦,快来抢沙发吧~