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