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)
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:
Second, your copy constructor takes a reference and not a
constreference which means that you can’t use it with a temporaryFoo.Personally, I’d just remove
explicitfrom the copy-constructor and make it take aconstreference if possible.Note that the
expliciton your default constructor has no effect.[*]explicitonly 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:
and
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 anexplicitdefault constructor. Perhaps someone can point out a corner case where it does make a difference but for now I don’t see what effectexplicithas on a default constructor.