Default Constructor's Private Shadow
When declaring a type with the intention of making its default constructor private, using the default keyword might not achieve the desired result, as illustrated in the following code snippet:
class C { C() = default; }; int main() { C c; // error: C::C() is private within this context (g++) // error: calling a private constructor of class 'C' (clang++) // error C2248: 'C::C' cannot access private member declared in class 'C' (MSVC) auto c2 = C(); // error: as above }
Surprisingly, this code generates errors despite explicitly making the constructor private. However, the following code compiles successfully:
class C { C() = default; }; int main() { C c{}; // OK on all compilers auto c2 = C{}; // OK on all compilers }
Why does the constructor behave differently when used with curly braces?
C 14 Default Constructor Defaultness
The key lies in the C 14 standard (8.4.2/5 [dcl.fct.def.default]), which defines a "user-provided" function as one that is "user-declared and not explicitly defaulted or deleted on its first declaration." This implies that the default constructor in our example is not considered user-provided since it was explicitly defaulted.
Aggregate Constructor Illumination
As a result, the class C has no user-provided constructors. It is, therefore, classified as an aggregate according to 8.5.1/1 [dcl.init.aggr], which states that an aggregate is "an array or a class with no user-provided constructors, no private or protected non-static data members, no base classes, and no virtual functions."
Aggregate Construction with Braces
Aggregates have a special construction rule that allows them to be constructed using curly braces {} even if they have private constructors. This rule is intended to simplify the initialization of aggregates, such as arrays and structs, that typically contain multiple members.
Hence, the constructor of class C, while marked as private, can still be used within curly braces because the class itself is considered an aggregate.
The above is the detailed content of Why does a private default constructor in C work when used with curly braces but fail with parentheses?. For more information, please follow other related articles on the PHP Chinese website!