完美转发指函数模板按原值类别转发参数,std::forward与通用引用T&&配合可实现此特性,保持左值/右值属性,避免拷贝并正确调用重载函数。

在C++11中,std::forward 是实现完美转发的关键工具。它的作用是保持传入参数的左值/右值属性,将参数原样传递给另一个函数,常用于模板函数中转发参数。
什么是完美转发?
完美转发指的是:一个函数模板能够将其参数以原来的值类别(左值或右值)原封不动地传递给另一个函数。这样可以避免不必要的拷贝,提升性能,并正确调用重载函数(如移动构造函数或拷贝构造函数)。
std::forward 的基本用法
std::forward 通常与通用引用(也叫转发引用)一起使用。通用引用的形式是 T&&,其中 T 是模板参数。
示例:
立即学习“C++免费学习笔记(深入)”;
#include#include #include void func(std::string& s) { std::cout << "Lvalue: " << s << "\n"; } void func(std::string&& s) { std::cout << "Rvalue: " << s << "\n"; } template void wrapper(T&& arg) { func(std::forward (arg)); }
解释:
T&&
是通用引用,能接受左值和右值。- 当传入左值时,T 被推导为左值引用(如
std::string&
),std::forward
就变成左值转发。(arg) - 当传入右值时,T 被推导为非引用类型(如
std::string
),std::forward
将其作为右值转发。(arg)
实际调用效果
继续上面的例子:
int main() {
std::string s = "hello";
wrapper(s); // 调用 func(std::string&)
wrapper("world"); // 调用 func(std::string&&)
return 0;
}
输出:
Lvalue: hello Rvalue: world
说明
std::forward成功保留了原始参数的值类别。
关键规则和注意事项
-
必须使用模板参数 T:只有在通用引用上下文中,
T&&
才具备自动推导能力,std::forward
才能正确工作。 -
不要对非通用引用使用 std::forward:例如
void foo(const std::string&& s)
中的 s 不是通用引用,不能用std::forward
转发。 - std::forward 不转发对象本身,而是表达式的值类别:它通过条件转换实现静态_cast 到 T& 或 T&&。
基本上就这些。掌握
std::forward和通用引用的配合,就能在模板中实现高效、正确的参数传递。不复杂但容易忽略细节。










