That is expected. If you pass an argument to a reference type parameter (whether lvalue or rvalue reference), the object will not be copied. That is the whole point of references.
The confusion you're having is pretty common. The choice of copy or move constructor only occurs when passing an object by value. For example:
void foo(A a);
When passing an A
object to this function, the compiler will determine whether to use the copy or move constructor depending on whether the expression you pass is an lvalue or rvalue expression.
On the other hand, none of the following functions would even try to invoke the copy or move constructor because no object is being constructed:
void foo(A& a);
void foo(const A& a);
void foo(A&& a);
void foo(const A&& a);
It's important to note that you should rarely (if ever) have any reason to write a function, other than a move constructor/assignment operator, that takes an rvalue reference. You should be deciding between passing by value and passing by const
lvalue reference:
If you're going to need a copy of the object inside the function anyway (perhaps because you want to modify a copy or pass it to another function), take it by value (A
). This way, if you're given an lvalue, it'll have to be copied (you can't avoid this), but if you're given an rvalue, it'll be optimally moved into your function.
If you're not going to need a copy of the object, take it by const
lvalue reference (const A&
). This way, regardless of whether you're given an lvalue or rvalue, no copy will take place. You shouldn't use this when you do need to copy it though, because it prevents you from utilising move semantics.
From the sounds of it, you're not going to make any copies at all, so a const A&
parameter would work.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…