The quoted paragraphs in the two versions of the Draft (N3797 and N3337) are the same:
A default constructor for a class X is a constructor of class X that can be called without an argument. If there is no user-declared constructor for class X, a constructor having no parameters is implicitly declared as defaulted (8.4). An implicitly-declared default constructor is an inline public member of its class. A defaulted default constructor for class X is defined as deleted if:
- X is a union-like class that has a variant member with a non-trivial default constructor,
- any non-static data member with no brace-or-equal-initializer is of reference type,
- any non-variant non-static data member of const-qualified type (or array thereof) with no brace-or-equal-
initializer does not have a user-provided default constructor,- X is a union and all of its variant members are of const-qualified type (or array thereof),
- X is a non-union class and all members of any anonymous union member are of const-qualified type (or array thereof),
- any direct or virtual base class, or non-static data member with no brace-or-equal-initializer, has class type M (or array thereof) and either M has no default constructor or overload resolution (13.3) as applied to M’s default constructor results in an ambiguity or in a function that is deleted or inaccessible from the defaulted default constructor, or
- any direct or virtual base class or non-static data member has a type with a destructor that is deleted or inaccessible from the defaulted default constructor.
I'll start with the 4th bullet point. As you can see here (http://rextester.com/HCPP94321) and here (http://rextester.com/HHQUB4028), the results vary for the compilers VS2013, clang and g++, and it appears to me that the only one respecting this bullet point in the Standard is clang, as I'll try to explain below:
The first snippet
#include <iostream> union U { const int i; const double x; char c; }; int main() { U u; }
shows one non-constant variant-member in the union U. This should compile without a problem. But that's not what happens. I summarize below the results for the three compilers:
VS2013 - error C2512: 'U' no appropriate default constructor available
clang - Ok (no error message)
g++ - error: uninitialized const member in 'Union U'
note: 'U::i' should be initialized
error: uninitialized const member in 'Union U'
note: 'U::x' should be initialized
The second snippet
#include <iostream> union U { const int i; const double x; const char c; }; int main() { U u; }
shows all variant members in the Union constant, which is the subject of the 4th bullet point above. See below the results for each compiler:
VS2013 - the same error C2512
clang - error: call to implicitly-deleted default constructor of 'U'
note: default constructor of 'U' is implicitly deleted because all data members are const-qualified
g++ - the same errors listed above
Assuming clang is correct, I can understand the reason for the implicit deletion of the default constructor in this case, i.e., to avoid an uninitialized object of a union, where all variant-members are constant.
Now lets consider the third bullet point above:
- any non-variant non-static data member of const-qualified type (or array thereof) with no brace-or-equal-
initializer does not have a user-provided default constructor,
Here I don't see the need for this implicit deletion of the default constructor, for the compiler will always show an error for a class constant member which is not initialized, as you can see here (http://rextester.com/AOI2981). That is, what's the reason for this bullet point?