Search code examples
c++c++11move

Is repeatedly calling move with rvalue references necessary?


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));
}

Give that you're calling move in main() to invoke the rvalue reference methods, is it necessary in lines A & B & C to repeat an additional call to move()? You already have the rvalue reference, so is it doing anything different in those lines with vs without?

I understand in Bar's operator= it's necessary because you're technically moving the m_Val rather than _other itself correct?

Note: Originally, I was incorrectly calling rvalue references as rvalue parameters. My apologies. I've corrected that to make the question easier to find and make clearer.


Solution

  • Give that you're calling move in main() to invoke the rvalue parameter methods, is it necessary in lines A & B & C to repeat an additional call to move()?

    Yes. What you call an rvalue parameter is actually an rvalue reference. Just like a lvalue reference, it is an lvalue in the scope that it is being used. That means you need to use move to cast it back into an rvalue so that it gets moved, instead of copied. Remember, if the object has a name, it is an lvalue.