CodeWalk

完美转发(Perfect Forwarding)与std::forward

作者:专业代码师 · 2026-05-30 12:55

请解释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内部实现、异步调用包装。