Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing move constructor

In the line commented by ***, why is Bar's copy constructor called? input_bar is a rvalue reference, so I expect the move constructor to be called. Did it convert to an lvalue reference? I can make the move constructor call if I change that 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;
}
like image 896
Agrim Pathak Avatar asked Dec 20 '22 08:12

Agrim Pathak


1 Answers

Once an entity has a name, it is clearly an lvalue! If you have a name for an rvalue reference, the entity with the name is not an rvalue but an lvalue. The entire point is that you know that this entity references an rvalue and you can legitimately move its content.

If you want to just forward the rvalueness to the next function you call, you'd use std::move(), e.g.:

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

Without the std::move() the rvalue is considered to be owned by the constructor. With the std::move() it releases the ownership and passes it on to the next function.

like image 147
Dietmar Kühl Avatar answered Dec 21 '22 21:12

Dietmar Kühl