myschu
myschu

Reputation: 91

Why do I need const copy constructor when compiling my code with converting constructor?

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.

Upvotes: 3

Views: 120

Answers (2)

SergeyA
SergeyA

Reputation: 62583

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)

Upvotes: 11

NathanOliver
NathanOliver

Reputation: 180630

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,

Upvotes: 9

Related Questions