【问题标题】:Is repeatedly calling move with rvalue references necessary?是否需要重复调​​用带有右值引用的移动?
【发布时间】:2019-07-22 14:17:57
【问题描述】:
struct Bar
{    
   Bar(std::string&& val)
    : m_Val(std::move(val)) {} // A

  Bar& operator=(Bar&& _other) { m_Val = std::move(_other.m_Val); }
  std::string m_Val;
}

struct Foo
{
  void Func1(Bar&& param)
  {
     Func2(std::move(param)) // B
  }

  void Func2(Bar&& param)
  {
     m_Bar = std::move(param); // C
  }

  Bar m_Bar;
};

void main()
{
   Foo f;
   std::string s = "some str";
   Bar b(std::move(s));
   f.Func1(std::move(b));
}

假设您在main() 中调用move 来调用右值引用方法,是否有必要在A、B 和C 行中重复对move() 的额外调用?你已经有了右值引用,那么它在那些有 vs 没有的行中有什么不同吗?

我在 Bar 的 operator= 中了解到这是必要的,因为您在技术上是在移动 m_Val 而不是 _other 本身是否正确?

注意:最初,我错误地将右值引用称为右值参数。我很抱歉。我已经更正了这一点,以使问题更容易找到并更清楚。

【问题讨论】:

  • 我知道您这样做可能是为了说明您的观点,但请注意,在您当前的示例中,您根本不需要编写 Bar 的移动构造函数。
  • 没有“右值参数”之类的东西。 named 引用生成一个 lvalue 表达式(是的,即使是右值引用也是左值)。因此,为了再次将其变为 xvalue,您需要再次应用 std::move
  • @AnT 我仍然对你的头像应该是什么感到困惑。
  • @SombreroChicken - 为什么?如果我在main中制作字符串,我不需要移动它吗?整个事情,包括字符串都是人为的,但我的理解是,如果我想避免复制它,我需要移动它。
  • @user99999991 SombreroChicken 意味着对于这个struct,在您的示例编译器中将隐式生成正确的移动 ctor 和移动赋值运算符,因此无需在此处手动定义它们。

标签: c++ c++11 move


【解决方案1】:

假设您在main() 中调用move 来调用右值参数方法,是否有必要在A、B 和C 行中重复对move() 的额外调用?

是的。你所说的右值参数实际上是一个右值引用。就像左值引用一样,它是正在使用的范围内的左值。这意味着您需要使用 move 将其转换回右值,以便移动而不是复制它。请记住,如果对象有名称,它就是左值

【讨论】:

  • 如果你说明原因,你会改进这一点。基本上,因为参数可以在函数体中多次使用。
  • 我确实希望你把这个加粗; "..如果对象有名字,它就是一个左值" ;.因为这是每个人都应该记住的关键......
猜你喜欢
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 2013-08-11
  • 2011-07-04
  • 2015-09-21
  • 1970-01-01
  • 2022-01-23
  • 2019-03-12
相关资源
最近更新 更多