Reputation: 6240
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
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
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
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