c++ - 在什么情况下,从 std::forward 赋值优于从 std::move 赋值?为什么?

标签 c++ move-semantics perfect-forwarding

cppreference.com上学习std::exchange ,我发现了它的“可能的实现”,粘贴在下面。

  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 到右值引用类型(但更具表现力),并且始终返回 xvalue,而 std::forward 返回与传递的值类型相同的值类型。

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

最佳答案

分配的事实是无关紧要的。 forward 和 move 的区别在于它们在函数内部使用时采用什么样的参数:

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

如果您与左值交换,您不希望将其移出!

例如,考虑:

std::vector<int> a, b;

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

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

另请参阅this answer我的,以及许多其他相关答案,例如 What is std::move(), and when should it be used? , What's the difference between std::move and std::forward ,以及其中的链接。

关于c++ - 在什么情况下,从 std::forward 赋值优于从 std::move 赋值?为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54374677/

相关文章:

c++ - 为什么 std::sort 找不到合适的(静态成员)函数重载?

c++ - 为什么要在单例中删除 move 构造函数和 move 赋值运算符?

c++ - 引用折叠和元组

c++ - 为什么添加一个析构函数(即使是空的)会破坏我使用引用转发和折叠来保存引用或值拷贝的结构?

c++ - 为什么 `const int ci = 2; std::forward<int>(ci);` 不起作用以及如何修复/解决它?

c++ - 我可以使用命名空间中的一些但不是全部名称,而不必为所有名称重复完整范围吗?

c++ - 如何正确地遍历 const 集?

c++ - 如何让Win32 APP背景透明?

c++ - 为什么这个 RAII 只 move 类型不能正确模拟 `std::unique_ptr` ?

c++ - 使用 C++ 的 std::move 从内部范围内的对象到外部范围安全吗?