Kolyunya
Kolyunya

Reputation: 6240

Converting constructor

Trying to compile the code:

class Foo
{
    public:
        Foo(Foo&){}
        Foo(int*){}
};

int main()
{
    int i = 2;
    Foo foo = &i;
    return 0;
}

Getting this:

prog.cpp: In function ‘int main()’:
prog.cpp:11:16: error: no matching function for call to ‘Foo::Foo(Foo)’
prog.cpp:11:16: note: candidates are:
prog.cpp:5:9: note: Foo::Foo(int*)
prog.cpp:5:9: note:   no known conversion for argument 1 from ‘Foo’ to ‘int*’
prog.cpp:4:9: note: Foo::Foo(Foo&)
prog.cpp:4:9: note:   no known conversion for argument 1 from ‘Foo’ to ‘Foo&’

I expected that on the Foo foo = &i line should be called the Foo(int*) c-tor.

Why does the compiler try to find Foo::Foo(Foo) c-tor instead?

Why doesn't it just use the Foo(int*) c-tor which is present?

Why the code will DO compile when I add const to the parameter of the first c-tor?

Why the code will DO compile when I remove the firs c-tor completely?

Thanks!

Upvotes: 2

Views: 191

Answers (4)

David G
David G

Reputation: 96810

Foo foo = &i;

This line creates a temporary Foo object with a parameter of &I. This is what the compiler returns the line into:

Foo foo = Foo(&i);

Then it will try to copy-construct the temporary which it can't do because the constructor you created Foo(Foo&) overrides the copy-constructor. Add the following constructor to your code for it to work:

Foo(Foo const& other) {}

Upvotes: 1

leemes
leemes

Reputation: 45675

Your first constructor is a copy constructor which can not be used to copy from temporaries. For this, you need to add const, so the signature becomes Foo(const Foo&).

The following code also compiles (a proper call to the constructor taking an int*):

Foo foo(&i);

Your code creates a (temporary) object Foo on the right hand side of the assignment operator and then assigns this object (using the (missing) copy constructor) to foo.

The compiler typically generates a copy constructor for you automatically, which takes a const reference. But since you defined a constructor taking a Foo&, the compiler doesn't generate such a copy constructor for you. So removing your first constructor also makes the code compile.

Upvotes: 5

Ray Tayek
Ray Tayek

Reputation: 10003

Foo foo = &i will not do what you think, try Foo foo=Foo(&i)

Upvotes: -3

Some programmer dude
Some programmer dude

Reputation: 409176

It's because the the compiler already creates an instance of Foo with the expression &i. It then tries to copy that into the destination variable foo, but as you don't have a proper copy-constructor it will not work.

A proper copy-constructor would have the signature Foo(const Foo&). Note the const.

Upvotes: 2

Related Questions