How is the initialization formed correctly?

The example in [class.conv.ctor] / 2 contains the following initialization:

Z a3 = Z(1); // OK: direct initialization syntax used 

How is this considered direct initialization syntax?

+5
source share
3 answers

Z(1) will direct-initialize the prvalue. Then prvalue will be used to initialize the object. According to the rules of guaranteed conflict resolution , there are no temporary copies. The prvalue function initializes the object directly. Therefore, Z a3 = Z(1); exactly equivalent to Z a3(1); .

In pre-C ++ 17, this will lead to a direct initialization of the temporary value prvalue, followed by (almost certainly) a copy of the temporary object a3 . Regardless of whether copying is performed or not, prvalue initialization is done through direct initialization. The initialization of a3 is done using copy initialization, but this is through the copy constructor, which is not explicit .

+8
source

He is talking about Z(1) . [Dcl.init] / 16:

The initialization that occurs in the [...] functional type of notation (5.2.3) [...] is called direct initialization.

Then the prvalue value is used to copy-initialize z , which is just fine, guaranteed by elision or not - z The copy / move constructors are not explicit anyway, so initialization is fine even without guaranteed elision in C ++ 17.

+4
source

(Caution: I am not familiar with the new concepts yet, but the following analysis seems correct). First you need to start with the functional expression Z(1); . Note that this prvalue expression is said to initialize some result object using direct initialization. Which this object remains unspecified and resolved later, and not by this functionally cast expression!

Now about prvalues โ€‹โ€‹result objects

The result of the prvalue object is an object initialized with the value prvalue; ... [... For a dropped evaluation, a temporary object materializes; see section [expr] ....]

Let us first make an example for the case Z(1); which should help to understand the concept. This expression is an expression that is the discarded value of the expression. For such expressions, the rule reads:

... If the expression is prvalue ..., a temporary materialization transformation ([conv.rval]) is applied.

And whenever this "temporary transformation of materialization" is applied, a temporary object is created and initialized from this value.

This conversion initializes a temporary object ([class.temporary]) of type T from prvalue, evaluating the prvalue with the temporary object as its final object and returns an x โ€‹โ€‹value representing the temporary object

Wow, all this is necessary for a simple statement of type Z(1); . Now about your case, Z a3 = Z(1); . For this, the result object is more directly determined by 8.6p17

If the initializer expression is prvalue, and the cv-unqualified version of the source type is the same class as the destination class, the initializer expression is used to initialize the target.

Viola, there is an expression whose semantics โ€œdirectly initializes the still unknown object X by 1โ€, and then another rule supplies this object โ€œXโ€. In particular, the pre-C ++ 17 model that creates objects that create objects of the prvalue class directly creates objects, is deprecated. This, in particular, means that the constructor or move constructor is not involved, but your code is exactly equivalent to Z a3(1) , as far as I can see.

+2
source

All Articles