Lol4t0
Lol4t0

Reputation: 12547

Can't understand compiler's behaviour (creating object)

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

Answers (3)

PierreBdR
PierreBdR

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

Sarfaraz Nawaz
Sarfaraz Nawaz

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

Fred Foo
Fred Foo

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

Related Questions