在哪些情况下 std::forward 的赋值优于 std::move 的赋值?为什么?

What are the scenarios where assignment from std::forward is preferable over assignment from std::move ? why?

cppreference.com 上了解 std::exchange 时,我偶然发现了粘贴在下面的 "possible implementation"。

  template<class T, class U = T>
  T exchange(T& obj, U&& new_value)
  {
      T old_value = std::move(obj);
      obj = std::forward<U>(new_value);
      return old_value;
  }

在赋值语句中看到 obj = std::forward 而不是 std::move 看起来有点奇怪,我认为这会产生相同的效果。

我的理解是 std::move 等同于 static_cast 右值引用类型(但更具表现力)并且 returns 总是一个 xvalue,而 std::forward returns 传递的值类型相同。

我的问题是为什么上面的代码片段中使用了 std:forward?是否有简单的经验法则来决定何时这是更好的选择?

有作业这一事实无关紧要。 forward 与 move 的区别在于它们在您的函数内部使用时采用哪种 argument

  • forward 的参数是您函数的转发引用参数。
  • move 的参数是您函数的右值引用参数(或者更一般地说,任何您知道没有其他别名的参数)。

如果你 exchange 有一个左值,你不希望它被移动!

例如,考虑:

std::vector<int> a, b;

f(std::exchange(a, b));

这有效地调用了 f(a),但也执行了 a = b;。它执行a = std::move(b)b 之后仍然可以原样使用!

另请参阅 this answer of mine, as well as many other related answers like What is std::move(), and when should it be used?, What's the difference between std::move and std::forward 以及其中的链接。