This code doesn't compile in VS2010. It emits error C2440: 'argument' : cannot convert from 'A' to 'A &', but according to 12.8p2 in the Standard, A::A(A&)
is a valid copy constructor and a
is an lvalue in the expression A b = foo(a);
in main()
.
#include <iostream>
class A
{
public:
int x;
A(int a) { x = a; std::cout << "Constructor\n"; }
A(A& other) { x = other.x; std::cout << "Copy ctor\n"; }
A(A&& other) { x = other.x; other.x = 0; std::cout << "Move ctor\n"; }
};
A foo(A a)
{
return a;
}
int main(void)
{
A a(5);
A b = foo(a);
}
I would say it depends on what standard you are talking about. Assuming C++11 then my take is that it should be OK and should produce the following result:
Constructor <- Construction of 'a' in main
Copy ctor <- Construction of 'a' in foo
Move ctor <- Move from foo's return value into b
As you point out the a that gets passed into foo is an lvalue. However, the return value from foo is an rvalue and should therefore invoke either the const A& copy constructor (non-existent) in the pre C++11 case, or the move constructor in the C++11 case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With