Look at the following code:
struct node
{
node();
//node(const node&); //#1
//node(node&&); //#2
virtual //#3
[C++11: 12.8/9]:
If the definition of a classX
does not explicitly declare a move constructor, one will be implicitly declared as defaulted if and only if
X
does not have a user-declared copy constructor,X
does not have a user-declared copy assignment operator,X
does not have a user-declared move assignment operator,X
does not have a user-declared destructor, and- the move constructor would not be implicitly defined as deleted.
[ Note: When the move constructor is not implicitly declared or explicitly supplied, expressions that otherwise would have invoked the move constructor may instead invoke a copy constructor. —end note ]
That's why your #3 is breaking the synthesis.
In addition, it's far from clear that volatile types (including your node* volatile) are trivially copyable; it could be concluded that it is implementation-defined whether they are or not and, in your case, it seems that they are not.
At the very least, GCC made it stop working quite deliberately in v4.7, with a proposal to backport into v4.6.1 that I can only presume went ahead...
So, given the following:
[C++11: 12.8/11]:
An implicitly-declared copy/move constructor is an inline public member of its class. A defaulted copy/move constructor for a classX
is defined as deleted (8.4.3) ifX
has:
- a variant member with a non-trivial corresponding constructor and
X
is a union-like class, a non-static data member of class typeM
(or array thereof) that cannot be copied/moved because overload resolution (13.3), as applied toM
’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 toB
’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.
... that's why your #4 is breaking the synthesis too, independently of #3.
As for #5, that's not actually a declaration of a node
at all, but a declaration for a function called m
— that's why it's not reproducing the symptoms related to construction of a node
(this is known as the Most Vexing Parse).