Reputation: 12547
I wrote the following code:
#include <iostream>
class A
{
public:
A(){ std::cout << "created" << std::endl; }
A(A& other) { std::cout << "copied" << std::endl; }
A& get(){ std::cout <<"got" << std::endl; return *this; }
~A(){ std::cout << "destroyed" << std::endl; }
};
Now, lines
A a = A().get();
and
A a;
a = A();
compile and work correctly, but
A a = A();
claims:
no matching function for call to ‘A::A(A)’
note: candidates are: A::A(A&)
note: A::A()
And to make things explicit,
A a = (A&)A();
claims:
error: invalid cast of an rvalue expression of type ‘A’ to type ‘A&’
I completely don't understand this behaviour.
P.S. I know, that if I make const
reference in copy c_tor, everything will be OK.
Upvotes: 2
Views: 1274
Reputation: 43254
This is simple: a rvalue (i.e. something that must be on the right hand side of an equal sign), can convert to a constant reference or be copied. Only a lvalue (i.e. something that can be placed on the left of an equal sign) can be converted into a non-constant reference. The reason being that you may be tempted to modify the content of the non-constant reference, which would be invalid.
A()
is a rvalue, and therefore cannot be converted into a non-constant reference. This is your error.
Upvotes: 3
Reputation: 361472
A a = A();
This line tries to call the copy-constructor passing a temporary object, and the copy-constructor takes argument by non-const reference. But a temporary object cannot be bound to a non-const reference. That is why you get the compilation error.
However, a temporary object can be bound to const
reference. So, the solution is to make the parameter const
reference as:
A(const A& other) { std::cout << "copied" << std::endl; }
Upvotes: 2
Reputation: 363587
The copy constructor should get its argument as a const
reference (or a simple A
value). In your current setup, the program would have to make a mutable reference to a temporary, which is invalid.
Upvotes: 3