简体   繁体   中英

Are these vector definitions “constant initialization”?

This question is about the code (at namespace scope):

std::vector<int> v1;
std::vector<int> v2(4);

In section 3.6.2 of C++14 (N4140) there is defined a term Constant initialization :

Constant initialization is performed:

  • [omitted - about reference initialization]
  • if an object with static or thread storage duration is initialized by a constructor call, and if the initialization full-expression is a constant initializer for the object;
  • if an object with static or thread storage duration is not initialized by a constructor call and if either the object is value-initialized or every full-expression that appears in its initializer is a constant expression.

Further, the term constant initializer is defined just earlier:

A constant initializer for an object o is an expression that is a constant expression, except that it may also invoke constexpr constructors for o and its subobjects even if those objects are of non-literal class types.

So, looking at std::vector<int> v2(4) .

This object is initialized by a constructor call so it's covered by the second bullet point. The initialization full-expression is 4 . 4 is a constant expression, therefore it is a constant initializer . So the second bullet point is satisfied and this should be a case of constant initialization .

However, I tested with a few compilers and all of them seem to treat v2 as dynamic initialization .

For the v1 case, it's not clear whether this counts as "initialized by a constructor call"; and if so, what the initialization full-expression would be.

My question is: are v1 and v2 constant initialization , or dynamic initialization ; and if the latter, could it be explained how these quotes from the standard are meant to be interpreted?

As per 1.9/10, the full expression of an initialization includes the call to the constructor:

A full-expression is an expression that is not a subexpression of another expression. ... If a language construct is defined to produce an implicit call of a function, a use of the language construct is considered to be an expression for the purposes of this definition. ... Conversions applied to the result of an expression in order to satisfy the requirements of the language construct in which the expression appears are also considered to be part of the full-expression.
[ Example:
...

 S s1(1); // full-expression is call of S::S(int) 

Then, per 8.5/17, direct initialisation (which both v1 and v2 use) involves a constructor call.

Therefore, the constructor call is part of the "initialization full-expression" per the 2nd bullet point you quote. So the constructor call, and not just the 4 , is the full-expression. This in turn means that such a constructor must be constexpr to qualify as a constant initializer (per its definition, as you quoted). And since neither the default constructor nor the size_t constructor of std::vector are constexpr , the initialisation is not constant.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM