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

yng*_*ccc 9 c++ c++11 c++14

struct Point {
  int x = 0;
  int y = 10;
};

Point p = {1,};
p.x == 1;  // true
p.y == 10; // is this true?
Run Code Online (Sandbox Code Playgroud)

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

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

Lig*_*ica 13

C++ 98,C++ 03

非静态数据成员初始化程序(NSDMI)不存在; 这个问题不适用.


C++ 11

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

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

因此,无法在此处执行聚合初始化; 采用a的构造函数std::initializer_list将是您使用该初始化语法([C++11: 8.5.4/3])的唯一方法,但您也没有其中之一.

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


C++ 1Y

在即将推出的标准版本中,聚合的定义已经放宽,以允许您的类型被视为聚合(只要这两个成员都保留public!):

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

接下来,有一个规则可以保证您正在寻找的结果:

[n3936: 8.5.1/7]:如果列表中的initializer-clause少于聚合中的成员,那么未明确初始化的每个成员都应从其brace-or-equal-initializer初始化,或者如果没有bra-or-equal-initializer,从一个空的初始化列表(8.5.4).[例如:

struct S { int a; const char* b; int c; int d = b[a]; };
S ss = { 1, "asdf" };
Run Code Online (Sandbox Code Playgroud)

初始化ss.a1,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 } };
Run Code Online (Sandbox Code Playgroud)

ab具有相同的值 - 末端示例]

  • @Downvoter:为什么?您认为ISO工作组出错了哪个标准部分? (3认同)