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

168 views Asked by At

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?

2

There are 2 answers

0
David G On BEST ANSWER

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.

2
Jans On

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

Because when you define the constructor as defaulted you’re reestablishing the delete effect caused by the move constructor, defaulting the copy constructor has the same effect as explicitly defining it doing what the compiler would do.