c++ - 数组新表达式中的直接初始化与列表初始化

标签 c++ c++14 language-lawyer initializer new-expression

基本上,为什么这是有效的:

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

但这不是:

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

更一般地说,新表达式初始化器的规则是什么?

我发现了以下内容:

— 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.

那么第二种情况是否无效,因为像 T((5)) 这样的事情是无效的(直接从表达式 (5) 初始化)?或者是什么原因?

编辑:好吧,我对 (()) 的建议似乎很愚蠢,因为我看不出为什么它只适用于数组 new 表达式。

最佳答案

第一个是有效的,因为 list initialization (自 C++11 起),

new T { arg1, arg2, ... }

If T is an aggregate type, aggregate initialization is performed.

int[10]是数组类型,属于聚合类型,则aggregate initialization执行,

If the number of initializer clauses is less than the number of members and bases (since C++17) or initializer list is completely empty, the remaining members and bases (since C++17) are initialized by their default initializers, if provided in the class definition, and otherwise (since C++14) by empty lists, in accordance with the usual list-initialization rules (which performs value-initialization for non-class types and non-aggregate classes with default constructors, and aggregate initialization for aggregates). If a member of a reference type is one of these remaining members, the program is ill-formed.

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

第二个是direct initialization ,所以 new int[10](5); 表示从单个 int 5int[10]直接;这是无效的。

其实对于array new expression你不能指定一个非空的带括号的初始化器。

If type is an array type, an array of objects is initialized.

  • If initializer is absent, each element is default-initialized
  • If initializer is an empty pair of parentheses, each element is value-initialized.
  • If initializer is a brace-enclosed list of arguments, the array is aggregate-initialized. (since 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 :

A new-expression that creates an object of type T initializes that object as follows:

  • If the new-initializer is omitted, the object is default-initialized ([dcl.init]). [ Note: If no initialization is performed, the object has an indeterminate value. — end note ]

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

  • Otherwise, the new-initializer is interpreted according to the initialization rules of [dcl.init] for direct-initialization.

[dcl.init]/17 :

  • (17.1) If the initializer is a (non-parenthesized) braced-init-list or is = braced-init-list, the object or reference is list-initialized.

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

  • (17.4) If the initializer is (), the object is value-initialized.

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

  • (17.5) Otherwise, if the destination type is an array, the program is ill-formed.

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

关于c++ - 数组新表达式中的直接初始化与列表初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49663651/

相关文章:

c++ - 将正弦波或三角波转换为锯齿波

c++ - 嵌套参数包扩展失败

c++ - 变量模板的开销

c++ - 重载逗号运算符*真的*会影响其操作数的评估顺序吗?

C++ 声明顺序(在多变量声明行中)

c++ - 为什么Clang和MSVC不喜欢带有多余括号的成员typedef声明?

c++ - 不包含继承?

c++ - 如何使用 Qt 在 Linux 中读取文件设备?

c++ - boost::any_cast - 仅在隐式转换不可用时抛出?

c++ - 将字符串数组传递给函数