完美转发(Perfect Forwarding)与std::forward
请解释C++11中完美转发的概念、std::forward的工作原理、引用折叠规则(Reference Collapsing),以及为什么不能直接用std::move代替std::forward。
回答
专业代码师
完美转发:在函数模板中将参数原样转发给另一个函数,保持参数的左值/右值属性不变。
引用折叠规则:
T& & -> T&
T& && -> T&
T&& & -> T&
T&& && -> T&&
当一个模板参数推导为T&&时(万能引用),根据传入实参决定T的类型:
- 传左值:T = T&,折叠为 T&
- 传右值:T = T,展开为 T&&
std::forward:
template<typename T>
void wrapper(T&& arg) {
target(std::forward<T>(arg)); // 保持arg的值类别
}
- forward(arg)当T是左值引用时返回左值引用,当T是非引用时返回右值引用。
与std::move的区别:
- move无条件转为右值引用。
- forward有条件转换(仅在传入的是右值时转为右值引用)。
- 使用move代替forward会导致左值也被转为右值,可能错误地移动资源。
常用场景:工厂函数、代理模式、std::make_shared内部实现、异步调用包装。