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

在C++中,模板参数推导和引用折叠是理解泛型编程(尤其是完美转发和通用引用)的关键机制。它们共同支撑了现代C++中高效、灵活的接口设计,比如 std::make_unique、std::forward 和各种工厂函数。
当编译器根据函数调用的实参自动确定模板参数类型时,就发生了模板参数推导。最常见的场景是函数模板:
template<typename T>
void func(T param);
<p>func(42); // T 被推导为 int,param 类型是 int
func("hello"); // T 被推导为 const char[6],param 是 const char*</p>但推导行为会因参数类型的不同而变化。以下是几种常见情况:
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&&) 这样的明确右值引用就不是通用引用。
引用折叠是 C++11 引入的核心规则,用于解决“引用的引用”这种非法语法。规则如下:
T&& && → T&&T&& & → T&T& && → T&T& & → T&简化记忆:只要出现左值引用,结果就是左值引用;只有全是右值引用时,结果才是右值引用。
引用折叠在通用引用和 std::forward 中起关键作用。例如:
template<typename T>
void wrapper(T&& arg) {
target(std::forward<T>(arg)); // 保持原始值类别
}
当传入左值时,T 被推导为 U&(U 是实际类型),std::forward<u></u> 返回 U&;传入右值时,T 是 U,std::forward<u></u> 返回 U&&,从而实现完美转发。
结合模板推导、通用引用和引用折叠,可以实现函数模板将参数原样转发给另一个函数:
template<typename T, typename U&gt;
std::unique_ptr<T> make_unique(U&amp;& u) {
return std::unique_ptr<T>(new T(std::forward<U&gt;(u)));
}
无论 u 是左值还是右值,std::forward 都能正确保留其值类别,调用匹配的构造函数。
基本上就这些。掌握这些规则后,就能理解 STL 中大多数泛型代码的设计原理。
以上就是c++++中的模板参数推导规则_c++ универсальные ссылки与引用折叠的详细内容,更多请关注php中文网其它相关文章!
c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号