user-declared
means either user-provided (defined by the user), explicitly defaulted (= default
) or explicitly deleted (= delete
) in contrast with implicitly defaulted / deleted (such as your move constructor).
So in your case, yes the move constructor is implicitly deleted because the copy-constructor is explicitly deleted (and thus user-declared).
However, in that particular case, how would deleted copy constructor/assignment mess default move constructor/assignment?
It would not, but the standard does not make the difference between this case and a complicated one.
The shortest answer is that having an implicitly defined move-constructor with an explicitly deleted copy-constructor might be dangerous in some cases, the same when you have a user-defined destructor and no user-defined copy-constructor (see rule of three/five/zero). Now, you can argue that a user-defined destructor does not delete the copy-constructor, but this is simply a flaw in the language which cannot be removed because it would break a lot of old (bad) program. To quote Bjarne Stroustrup:
In an ideal world, I think we would decide on “no generation” as the default and provide a really simple notation for “give me all the usual operations.” [...] Also, a “no default operations” policy leads to compile time errors (which we should have an easy way to fix), whereas a generate operations by default policy leads to problems that cannot be detected until run time.
You can read more about this in N3174=10-0164.
Note that most people follow the rule of three/five/zero, and in my opinion you should. By implicitly deleting the default move-constructor, the standard is "protecting" you from mistakes and should have protected you a long time before by deleting copy-constructor in some cases (see Bjarne's paper).
Further reading if you are interested:
I think this question has practical importance because manual generation and esp. maintenance of such default functions is error prone, while at the same time, the (righteous) increase of the use of classes such as std::unique_ptr
as class members made non-copyable classes much more common beasts than they used to be.
Marking the move constructor as explicitly defaulted will solve this problem:
class Foo {
public:
Foo() = default;
Foo(Foo const &) = delete;
Foo(Foo&&) = default;
};
You get a non-copyable object with a default move constructor, and in my opinion these explicit declarations are better than implicit ones (e.g. by only declaring the move constructor as default
without deleting the copy-constructor).
Foo(Foo &&) = default;
– Ignore