c++standardscopy-constructordefault-copy-constructor

Why does defaulted-move-ctor inhibit implicit-copy-ctor but not defaulted-copy-ctor?


I seem to have encountered an example in which a defaulted move constructor seems to count as both user-declared and not-user declared depending on the situation:

struct Foo {
    int a;
    Foo():a(42){};
    //Foo(const Foo & other) = default;
    Foo(Foo && other) = default;

};

int main() {
    Foo f;
    Foo g = f;
}

results in this:

test.cpp:11:9: error: call to implicitly-deleted copy constructor of 'Foo'
    Foo g = f;
        ^   ~
test.cpp:5:5: note: copy constructor is implicitly deleted because 'Foo' has a user-declared move constructor
    Foo(Foo && other) = default;
    ^

The compiler error is expected, since cppreference tell us this:

The implicitly-declared or defaulted copy constructor for class T is defined as deleted if any of the following conditions are true:
[...]
T has a user-defined move constructor or move assignment operator;

Note, that the defaulted constructor apparently counts as "user-declared" here. However, if we now remove the comments from line 4, thereby explicitly defaulting the copy constructor, the program will compile without error, even though the statement I quoted above specifies:

The implicitly-declared or defaulted copy constructor

This seems like a contradiction. Is this an error in cppreference or am I simply confused?


Solution

  • This looks like an error on cppreference's part. Declaring a move constructor/assignment operator only deletes an implicitly declared copy constructor. Indeed declaring a copy constructor as default is user-declaring it and thus that doesn't apply to this case.