Initializing C ++ 14 value with remote constructor

I have a misunderstanding:

Mark the default constructor of structure A as remote:

struct A { A() = delete; }; 

The following instructions are well-formed and what is the effect?

 A a{}; 

From initializing the cppreference value :

1) If T is a class type without a default constructor or with a user-supplied default constructor or with a default constructor removed, the object is initialized by default.

but then the default initialization effect:

If T is a class type, the default constructor is invoked to provide an initial value for the new object.

Or is this a summary initialization? Thank!

+38
c ++ language-lawyer c ++ 14
May 27 '14 at 6:24
source share
2 answers

Your struct A :

  • type of class that has:
    • there are no constructors provided by user 1 ,
    • no private or protected non-static data members,
    • no base classes
    • no virtual member functions.

Therefore, it qualifies as an aggregate type in accordance with the definition set out in Β§ 8.5.1 / 1.

Then, the unit initialization priority is performed by the value initialization. The standard says that aggregate initialization takes precedence over cost initialization (project N3936, Β§ 8.5.4 / 3, p. 201) (emphasis added)

An initialization list of an object or link of type T is defined as follows:

  • If T is an aggregate, aggregate initialization is performed (8.5.1).
  • Otherwise, if there are no elements in the initializer list, and T is the class type with the default constructor, the object is initialized with a value.
  • [... more rules ...]

(1) As indicated in the comments on why the remote constructor is not taken into account as user-defined, this is what the standard says (project N3936, Β§ 8.4.2 / 5, p. 198):

A function is provided by the user if it is declared by the user and is clearly not defaulted or deleted in its first declaration.

+29
May 27 '14 at 7:03
source share

He is well formed. A is a collection of 1 and, according to project N3936 , an empty list of initializers used in direct -list initialization of the aggregate result in aggregate initialization:

From Β§ 8.5.4 / 3 List-initialization [dcl.init.list] :

An initialization list of an object or link of type T is defined as follows:

- If T is an aggregate, aggregate initialization is performed (8.5.1).

[Example:

struct S2 { int m1; double m2, m3; };

....

S2 s23{}; // OK: default to 0,0,0

....

- end of example]

....

The corresponding changes between C ++ 11 and C ++ 1y are a change in the priority of aggregate initialization and the value for the case of aggregates:

C ++ 11 leads with

An initialization list of an object or link of type T is defined as follows:

- If there are no elements in the initializer list, and T is the type class with the default constructor, the object is initialized with a value.

- Otherwise, if T is an aggregate, aggregate initialization is performed (8.5.1) ....

and then the example above.

C ++ 1y gives priority to aggregate initialization:

An initialization list of an object or link of type T is defined as follows:

- If T is an aggregate, aggregate initialization is performed (8.5.1).

....

- Otherwise, if there are no elements in the initializer list, and T is the class type with the default constructor, the object is initialized with a value.




1 Why A unit?

This is a collection in both C ++ 11 and C ++ 14.

C ++ 1y:

8.5.1 Aggregates [dcl.init.aggr]

An aggregate is an array or class (section 9) without constructors provided by the user (12.1), without private or protected non-static data elements (section 11), without base classes (section 10) and without virtual functions (10.3).

The only part that is not obvious is whether the default constructor is provided for the user or not. Is not:

In Β§ 8.4.2 [dcl.fct.def.default] :

A function is provided to the user if it is declared by the user and not explicitly by default or deleted in his first declaration.

+19
May 27 '14 at 7:03
source share



All Articles