完美转发(std::forward)

完美转发(std::forward)
枫完美转发(std::forward)
完美转发的目标可以用一句话概括:把收到的参数,尽可能原样地转交给下一个函数。
它是模板代码里非常常见的一项能力,核心工具就是std::forward。
1. 为什么需要它?
假设我们写一个中转函数:
1 | void target(const std::string& s) |
看起来没问题,但这里的 arg 在函数体里其实是一个左值。
也就是说,原本传进来如果是右值,中间这层包装后,右值语义可能就丢了。
2. std::forward 的作用
正确写法通常是:
1 | template <typename T> |
这样 arg 的值类别就能尽量保持不变。
3. 一个更直观的例子
1 |
|
输出:
1 | lvalue |
这就是“原样转发”的效果。
4. 万能引用和完美转发
T&& 在模板推导场景下,常被称作万能引用或转发引用。
它能根据传入参数是左值还是右值,推导出不同的类型,再配合 std::forward 实现完美转发。
5. 典型使用场景
5.1 工厂函数
1 | template <typename T, typename... Args> |
5.2 包装器和适配器
只要你的函数只是“接一下参数,再转交给别人”,大概率就会涉及完美转发。
6. std::move 和 std::forward 的区别
std::move
- 无条件把对象转成右值
std::forward
- 有条件地保持原始值类别
- 主要用于模板转发场景
所以中转模板里通常用 forward,不是 move。
总结
完美转发是现代 C++ 模板编程里很常见的一项能力。
它的目标不是“把东西都变成右值”,而是“别把原来传进来的左值/右值语义弄丢”。理解了这一点,再看 std::forward 就会清楚很多。














