3

I have such class in A.h :

class A { public: A(int *object) { std::cout << "convert"; } A(A &object) { std::cout << "copy"; } }; 

and in main.cpp

A a = new int; 

then, when I'm trying to compile it i get

invalid initialization of non-const reference of type ‘A&’ from an rvalue of type ‘A’

but when i add const to copy-constructor like that:

A(const A &object) { std::cout << "copy"; } 

code compiles and "convert" is called. It works when i remove copy constructor, too. Why such thing happen? I though this example has nothing to do with copying constructor as we do not use instance of class A to create another.

1
  • 3
    @NeilButterworth there is enough code to understand the problem. Commented May 22, 2018 at 16:09

2 Answers 2

11

Because the way your code works is following (pre-C++17):

A a(A(new int)); 

Note, copy constructor of A is called with a temporary object crated as a result of A(new int). And you can't bind a non-const lvalue reference to a temporary.

Just a note, in C++17 this code will compile due to guaranteed copy-elision (in case of C++17, this code is semantically equivalent to A a(new int). You also won't see copy printed (because it will never be called due to copy elision)

Sign up to request clarification or add additional context in comments.

3 Comments

To add: pre c++17 you probably won't see "copy" printed because the compiler actually elides the copy. The copy had to be well-formed though, even though it never ends up happening.
@MilesBudnek incorporated into an answer.\
Yes, exactly. I 'm working with c++11 and there was no "copy". Anyways, thank you all so much for answer.
9

A a = new int; is copy initialization. It takes what is on the right hand side and uses it to initialize what is on the left hand side as a copy of it. since new int isn't an A the compiler makes a temporary one calling the converting constructor. A temporary can't be bound to a non const reference so you get an error. When you add the const you can now bind the temporary to it and it will work. Removing the copy constructor also works as the compiler will provide one for you and the one it does takes in a const reference,

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.