【问题标题】:What are the scenarios where assignment from std::forward is preferable over assignment from std::move ? why?在哪些情况下,来自 std::forward 的赋值优于来自 std::move 的赋值?为什么?
【发布时间】:2019-06-19 20:14:21
【问题描述】:

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 返回它传递的相同值类型。

我的问题是为什么在上面的 sn-p 中使用std:forward?是否有一个简单的经验法则来决定何时这是更好的选择?

【问题讨论】:

    标签: c++ move-semantics perfect-forwarding


    【解决方案1】:

    有分配的事实是无关紧要的。 forward 与 move 的区别在于它们在您的函数中使用时所采用的 参数

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

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

    例如,考虑:

    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,以及其中的链接。

    【讨论】:

    • 错字:move 采用左值引用。它将 转换为 一个右值引用。
    • 感谢您的回答和链接。所以主要的是我们不想在函数内部强行将左值引用转换为右值,并可能使其无效。我当时正在查看的代码只是将 { } 作为第二个参数传递,但正如您所说,区别在于 b 是左值时。
    • @RichardHodges:不,我的意思是我写的,但我说得不好。我会调整的,谢谢。 (当然,forward 和 move 的典型参数始终是左值,因为它们通常是 id 表达式。)
    猜你喜欢
    • 2021-01-13
    • 2020-10-19
    • 2014-12-19
    • 2016-07-08
    • 1970-01-01
    • 2020-12-30
    • 2016-03-04
    • 1970-01-01
    • 2015-05-03
    相关资源
    最近更新 更多