7

Basically, why is this valid:

auto p1 = new int[10]{5};

but this is not:

auto p1 = new int[10](5);

And more generally what are the rules for the new-expression initializer?

I found the following:

— If the new-initializer is omitted, the object is default-initialized (8.5). [ Note: If no initialization is performed, the object has an indeterminate value. — end note ] — Otherwise, the new-initializer is interpreted according to the initialization rules of 8.5 for direct- initialization.

So is the second case invalid because smth like T((5)) is invalid (direct initialization from expression (5))? Or what is the reason?

EDIT: well, my suggestion of (()) thing seems dumb because I see no reason why that should only apply to array new-expression.

4

1 回答 1

7

由于列表初始化(C++11 起),第一个是有效的,

new T { arg1, arg2, ... }

如果 T 是聚合类型,则执行聚合初始化。

int[10]是一个数组类型,属于聚合类型,然后进行聚合初始化

如果初始化子句的数量少于成员的数量and bases (since C++17)或初始化列表完全为空,则剩余成员由空列表and bases (since C++17)初始化by their default initializers, if provided in the class definition, and otherwise (since C++14),按照通常的列表初始化规则(对非类类型执行值初始化和具有默认构造函数的非聚合类,以及聚合的聚合初始化)。如果引用类型的成员是这些剩余成员之一,则程序格式错误。

因此auto p1 = new int[10]{5};将创建一个指向数组的指针,其第一个元素初始化为5,其余元素初始化为0

第二个是直接初始化,即直接从一个new int[10](5);数组初始化;这是无效的。int[10]int 5

实际上,对于数组 new 表达式,您不能指定非空的带括号的初始化程序。

如果 type 是数组类型,则初始化对象数组。

  • 如果没有初始化器,则每个元素都是默认初始化的
  • 如果 initializer 是一对空括号,则每个元素都进行值初始化。
  • 如果初始化程序是用大括号括起来的参数列表,则数组是聚合初始化的。(C++11 起)

所以

auto p1 = new int[10];    // valid
auto p2 = new int[10]();  // valid
auto p3 = new int[10]{5}; // valid

auto p4 = new int[10](5); // invalid

编辑

正如您所引用的,从标准的角度来看,[expr.new]/18

创建 T 类型对象的 new 表达式按如下方式初始化该对象:

  • 如果省略 new-initializer,则对象是默认初始化的 ([dcl.init])。[ 注意:如果不进行初始化,则该对象具有不确定的值。——尾注]

=> 适用于auto p1 = new int[10];,导致默认初始化。

  • 否则,根据 [dcl.init] 的初始化规则解释 new-initializer 以进行直接初始化。

[dcl.init]/17

  • (17.1) 如果初始值设定项是(无括号的)braced-init-list 或者是 =braced-init-list,则对象或引用是列表初始化的。

=> 申请auto p3 = new int[10]{5};, 导致列表初始化,详情在上面解释。

  • (17.4) 如果初始值设定项是 (),则对象是值初始化的。

=> 适用于auto p2 = new int[10]();,导致值初始化。

  • (17.5) 否则,如果目标类型是数组,则程序格式错误。

=> 适用于auto p4 = new int[10](5);.

于 2018-04-05T03:40:35.223 回答