Move constructor implementation

On the line commented out ***, why is the Bar copy constructor called? input_bar

is an rvalue reference, so I expect you to call the move constructor. Did it convert to an lvalue reference? I can make a call to the move constructor if I change this line to bar_(std::move(input_bar))

.

#include <iostream>
#include <array>
#include <memory>

class Bar
{
public:   
  Bar(const Bar& bar)
  {
    std::cout << "copy constructor called" << std::endl;
  }

  Bar(Bar&& bar)
  {
    std::cout << "move constructor called" << std::endl;
  }
};

class Foo
{
public:
  Foo(Bar&& input_bar) :
    bar_(input_bar) // ***
  {
  }
  Bar bar_;
};

int main()
{
  Bar bar;
  Foo foo(std::move(bar));
  return 0;
}

      

+3


source to share


2 answers


Once an object has a name, it is explicitly lvalue! If you have a name for an rvalue reference, the entity named is not an r, but an lvalue. The point is that you know that this object is being referenced by an rvalue, and you can legally move its contents.

If you just want to redirect the rvalueness to the next function you call, you should use std::move()

for example:



Foo(Bar&& bar): bar_(std::move(bar)) {}

      

Without std::move()

, r is considered to be owned by the constructor. With help, std::move()

he releases the ownership and transfers it to the next function.

+8


source


You need to move rhrs:

  Foo(Bar&& input_bar) :
    bar_(std::move(input_bar)) // ***
  {
  }

      

We believe that when we do use RHR it should be semantically considered out of scope. Enforcement std::move

allows the following undefined code to be used:



 Foo(Bar&& input_bar) {
    std::cout << input_bar.baz << std::endl;//not undefined
    bar_ = Bar{std::move(input_bar)};//input_bar is now essentailly destroyted
    //std::cout << input_bar.baz << std::endl;//Undefined behavior, don't do this
 }

      

The general rule of thumb is that only things without names can actually be used as RHR ... RHR, since the arguments are named and thus will be treated as LHR until you name a function on them.

+2


source







All Articles