繁体   English   中英

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

[英]Partial Aggregate Initialization and Non-static Data Member Initializer

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的构造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] :如果列表中的初始化子句比集合中的成员少,那么未明确初始化的每个成员都应从其括号或等号初始化器初始化,或者如果有的话从空的初始化列表(8.5.4)开始,它不是大括号或等号初始值 [例如:

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

初始化ss.a1ss.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示例]

(在C ++ 1Y答有效, 只有 !)

根据“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’),

所以在你的例子中py将被初始化为10。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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