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?
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.