Reputation: 7809
Suppose, I have the following code. There's a copy constructor in B which calls a method which copies the resources of a.
Now I also have a move constructor. In this case, a should not be copied but just "steal" the resources from an existing a. Therefore, I also implemented an init taking an rvalue. But of course, when I try to call it with parameter b.a, this is an lvalue...
Is there a way to call this method?
class A{
A(const A&& a){
// 'steal' resources from a
}
void init(A& a){
// init this A from another A by copying its resources
}
void init(A&& a){
// init this A from another A stealing its resources and tell the other a, it must not destroy resources upon destruction
}
};
class B{
A a;
B(B& b){
a.init(b.a)
}
B(B&& b){
a.init(b.a); // How to call init(A&& a)?
}
};
Upvotes: 2
Views: 329
Reputation: 227390
b.a
is an lvalue, so you need to apply std::move
:
a.init(std::move(b.a));
Note: But why is b
an lvalue in the body of B(B&& b)
?
Here, the parameter type B&& b
simply means that this constructor overload will be chosen over, say, B(const B& b)
when invoked with an rvalue.
B make_B() { return B(); }
B b1(make_B()); // B(B&&) chosen
B b2(b); // B(const B&) chosen
But the parameter itself is an lvalue because it has a name. All std::move
does is make its argument look like an rvalue.
Upvotes: 7