部分聚合初始化和非静态数据成员初始化

Partial Aggregate Initialization and Non-static Data Member Initializer

本文关键字:初始化 静态 数据成员      更新时间:2023-10-16
struct Point {
  int x = 0;
  int y = 10;
};
Point p = {1,};
p.x == 1;  // true
p.y == 10; // is this true?

根据标准的初始化列表中缺失的元素是值初始化的,所以y应该是int()0,但它似乎没有说明在非静态数据成员初始化时发生了什么。

编辑:根据答案,显然这是无效的c++11,我想知道c++1y的情况。

c++ 98, c++ 03

不存在非静态数据成员初始化器(nsdmi);这个问题不适用。


c++ 11

首先,这个初始化是无效的,因为你的类型不是聚合:

[C++11: 8.5.1/1]: 聚合是一个数组或一个类(第9条)具有用户提供的构造函数(12.1),对于非静态数据成员(9.2)没有大括号或等于初始化式,没有私有或受保护的非静态数据成员(第11条),没有基类(第10条),没有虚函数(第10.3条)。

所以聚合初始化不能在这里执行;使用std::initializer_list的构造函数将是使用初始化语法([C++11: 8.5.4/3])的唯一方法,但是您也没有这些语法。

因此,这个问题的整个前提是有缺陷的:你不可能让自己进入这种状态。


C + + 1 y

在即将发布的标准版本中,聚合的定义已经放宽,允许您的类型被视为聚合(只要这些成员都保持public !):

[n3936: 8.5.1/1] 聚合是一个数组或一个类(第9条),没有用户提供的构造函数(12.1),没有私有或受保护的非静态数据成员(第11条),没有基类(第10条),没有虚函数(10.3)。

在此基础上,有一条规则可以保证您正在寻找的结果:

[n3936: 8.5.1/7]:如果列表中的初始化子句少于聚合中的成员数,则每个未显式初始化的成员应从其大括号或相等初始化项初始化,或者,如果没有大括号或相等初始化项,从空的初始化列表(8.5.4)。(例子:

struct S { int a; const char* b; int c; int d = b[a]; };
S ss = { 1, "asdf" };

ss.a初始化为1,将ss.b初始化为"asdf",将ss.c初始化为int{}(即0),将ss.d初始化为ss.b[ss.a](即’s’),并在

struct X { int i, j, k = 42; };
X a[] = { 1, 2, 3, 4, 5, 6 };
X b[2] = { { 1, 2, 3 }, { 4, 5, 6 } };

ab具有相同的值 -end example]

<一口> (回答有效的C + + 1 y, !)

根据章节"8.5.1骨料"第#7段(工作草案N3691日期:2013-05-16)

7如果列表中的初始化子句比实际的少成员,则每个成员未显式初始化必须从大括号或相等初始化式或初始化式初始化(如果有)在空初始化列表中没有大括号或相等初始化项吗(8.5.4)。

引号下面有一个例子

[ Example: struct S { int a; const char* b; int c; int d = b[a]; }; 
S  ss = { 1, "asdf" };
 initializes ss.a with 1, ss.b with "asdf", ss.c
with the value of an expression of the form int{} (that is, 0), and
ss.d with the value of ss.b[ss.a] (that is, ’s’),

在你的例子中,y将被初始化为10