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

后端 未结 10 2669
小鲜肉
小鲜肉 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:32

    A copy constructor shouldn't be explicit (which makes it uncallable here and in many other perfectly reasonable contexts, such as when passing or returning by value).

    Next it should take the argument by const reference, since otherwise it can't bind to temporaries.

    Foo f = Foo();
            ^^^^^
              |
              --- this is a temporary that cannot be passed to a function
                  that accepts a non-const reference
    

    Furthermore, there is no reason to make the default constructor explicit: this keyword only makes sense for constructors (other than the copy constructor) that can be called with exactly one argument, in which case it prevents implicit conversions of other types into Foo via that constructor. For example, if a constructor taking an int were explicit, situations like these wouldn't compile:

    Foo f;
    f = 1;  //assuming no operator= overload for (types convertible from) int
            //this implicitly performs f = Foo(1);
    
    Foo g = 10;
    
    void x(Foo);
    x(20);
    

    All in all:

    class Foo
    {
    public:
        Foo();
        Foo(const Foo&);
        //...
    };
    
    Foo x = Foo();
    

    And furthermore, if neither of those constructors is meant to do anything, you needn't define them at all - the compiler will provide them automatically (if you define any other constructors, the default constructor will not be automatically generated, though).

提交回复
热议问题