这是意料之中的。如果您将参数传递给引用类型参数(无论是左值还是右值引用),则不会复制该对象。这就是整个参考点。
你遇到的困惑很常见。只有在按值传递对象时才会选择复制或移动构造函数。例如:
void foo(A a);
将A对象传递给此函数时,编译器将根据您传递的表达式是左值表达式还是右值表达式来确定是使用复制构造函数还是移动构造函数。
另一方面,以下函数甚至都不会尝试调用复制或移动构造函数,因为没有正在构造对象:
void foo(A& a);
void foo(const A& a);
void foo(A&& a);
void foo(const A&& a);
重要的是要注意,除了移动构造函数/赋值运算符之外,您应该很少(如果有的话)编写一个接受右值引用的函数。您应该在通过值传递和通过const左值引用传递之间做出决定:
如果您无论如何都需要在函数中复制对象(可能是因为您想修改副本或将其传递给另一个函数),请按值 ( A) 获取它。这样,如果你得到一个左值,它就必须被复制(你无法避免这种情况),但如果你得到一个右值,它将被最佳地移动到你的函数中。
如果您不需要对象的副本,请通过const左值引用 ( const A&) 获取它。这样,无论您获得的是左值还是右值,都不会发生复制。但是,当您确实需要复制它时,您不应该使用它,因为它会阻止您使用移动语义。
从它的声音来看,您根本不会制作任何副本,因此可以使用const A&参数。