C++11 rules for automatic generation of special members aren't as simple as you posted them. The most important distinction is that in some cases, the member is implicitly declared, but defined as deleted. That's what happens in your case.
C++11, [class.copy]§11:
A defaulted copy/move constructor for a class X
is defined as deleted (8.4.3) if X
has:
- a variant member with a non-trivial corresponding constructor and
X
is a union-like class,
- a non-static data member of class type
M
(or array thereof) that cannot be copied/moved because overload resolution (13.3), as applied to M
's corresponding constructor, results in an ambiguity or a function that is deleted or inaccessible from the defaulted constructor,
- a direct or virtual base class
B
that cannot be copied/moved because overload resolution (13.3), as applied to B
's corresponding constructor, results in an ambiguity or a function that is deleted or inaccessible from the defaulted constructor,
- any direct or virtual base class or non-static data member of a type with a destructor that is deleted or inaccessible from the defaulted constructor,
- for the copy constructor, a non-static data member of rvalue reference type, or
- for the move constructor, a non-static data member or direct or virtual base class with a type that does not have a move constructor and is not trivially copyable.
(Emphasis mine)
More generally, the rules for auto-generated class members are:
If the class has no user-provided constructors, a default constructor is declared.
If the class doesn't have a user-provided copy constructor, one is declared.
If the class has none of { user-provided copy or move constructor, user-provided copy or move assignment operator, user-provided destructor }, a move constructor will be declared (but see (*) below).
If the class doesn't have a user-provided copy assignment operator, one is declared.
If the class has none of { user-provided copy or move constructor, user-provided copy or move assignment operator, user-provided destructor }, a move assignment operator will be declared (but see (*) below).
If the class doesn't have a user-provided destructor, one is declared.
Any automatically declared member can be defined as defaulted (doing the default stuff) or defined as deleted (if you try to use it, you get an error). The rule of thumb is "If the defaulted version makes sense, it will be defined as defaulted. Otherwise, it will be defined as deleted."
In this context, "makes sense" means "doesn't try to call a deleted, ambiguous, inaccessible or otherwise illegal function." For example, the standard bit I quoted in the first part of this answer lists what doesn't "make sense" for copy constructors.
Additionally, an automatically declared copy constructor or copy assignment operator is defined as deleted if the class has a user-provided move constructor or move assignment operator.
(*) If an automatically declared move constructor or move assignment operator would be defined as deleted, it is instead not declared at all. This rule exists so that trying to move such a class implicitly falls back to copying it instead of generating an error.
unique_ptr
cannot be copied, which causesUni
's copy constructor to be defined as deleted, which causes the compile error. When you write your own you obviously don't get this problem. – Simple