Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Foo f = Foo(); // no matching function for call to 'Foo::Foo(Foo)' ... huh?

Tags:

class Foo
{
public:
    explicit Foo() {}
    explicit Foo(Foo&) {}
};

Foo d = Foo();

error: no matching function for call to 'Foo::Foo(Foo)'

I tried changing Foo(Foo&) to Foo(Foo) as the error suggests, which AFAIK is not a valid constructor, and sure enough I get:

error: invalid constructor; you probably meant ‘Foo (const Foo&)’

What gives? How do I resolve this? (This is on GCC by the way)

like image 228
Kyle Avatar asked May 05 '10 19:05

Kyle


1 Answers

There are two questionable things that you have in your copy constructor.

First, you've made the copy-constructor explicit (which is a questionable thing to do), so you would (in theory) need to do:

Foo d( (Foo()) );

Second, your copy constructor takes a reference and not a const reference which means that you can't use it with a temporary Foo.

Personally, I'd just remove explicit from the copy-constructor and make it take a const reference if possible.

Note that the explicit on your default constructor has no effect.[*] explicit only has an effect on constructors that can be called with a single parameter. It prevents them being used for implicit conversions. For constructors that take only zero or only two or more parameters, it has no effect.

[Note: there can be a difference between:

Foo d;

and

Foo d = Foo();

but in this case you have a user-declared default constructor so this doesn't apply.]

Edit: [*] I've just double checked this and 12.3.1 [class.conv.ctor] says that you can make a default constructor explicit. In this case the constructor will be used to perform default-initialization or value-initialization. To be honest, I don't understand the value of this as if you have a user-declared constructor then it's a non-POD type and even local objects of non-POD type are default-initialized if they don't have an initializer which this clause says can be done by an explicit default constructor. Perhaps someone can point out a corner case where it does make a difference but for now I don't see what effect explicit has on a default constructor.

like image 170
CB Bailey Avatar answered Oct 06 '22 20:10

CB Bailey