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

后端 未结 10 2729
小鲜肉
小鲜肉 2021-02-19 20:13
class Foo
{
public:
    explicit Foo() {}
    explicit Foo(Foo&) {}
};

Foo d = Foo();

error: no matching function for call to \

10条回答
  •  执念已碎
    2021-02-19 20:37

    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.

提交回复
热议问题