【问题标题】:C++: flat initializer list for nested struct?C++:嵌套结构的平面初始化列表?
【发布时间】:2017-05-03 22:09:42
【问题描述】:

已定义

struct A {
  int a,b;
};

struct B {
  A a;
  int b;
};

以下初始化是显而易见的:

B b1 = { { 1 } };    // initializes b1.a.a
B b2 = { { 1, 2 } }; // initializes b1.a.a, b1.a.b
B b3 = { { 1 }, 2 }; // initializes b1.a.a, b1.b

但令我惊讶的是 VC++ 2013 也允许这些初始化而没有任何警告:

B b4 = { 1 };       // initializes b4.a.a
B b5 = { 1, 2 };    // initializes b5.a.a, b5.a.b
B b6 = { 1, 2, 3 }; // initializes b6.a.a, b6.a.b, b6.b

嵌套结构/类的平面初始化列表是标准 C++ 吗?

【问题讨论】:

  • 仅供参考:在您的所有示例中,所有元素都已初始化。未指定的初始化为 0。
  • 是的,这来自 C.

标签: c++ c++11 visual-c++ visual-studio-2013


【解决方案1】:

是的,它是8.5 Initializers中描述的标准C++

这称为大括号省略,可以应用于聚合初始化的情况。

来自 n42968.5.1.12 聚合

可以在初始化列表中省略大括号,如下所示。如果 initializer-list 以左大括号开头,然后是后面的 初始化子句的逗号分隔列表初始化 子聚合;有更多是错误的 初始化子句比成员。但是,如果初始化器列表 对于子聚合不以左大括号开头,则仅 从列表中获取足够的初始化子句来初始化 子集合的成员;任何剩余的初始化子句都是 left 来初始化聚合的下一个成员,其中 当前子聚合是成员。

这是 8.5.1.13 中的另一个示例:

struct A {
    int i;
    operator int();
};

struct B {
    A a1, a2;
    int z;
};

A a;
B b = { 4, a, a };

在本例中,a14 初始化,a2az 初始化 使用 aoperator int() 的结果进行初始化。

【讨论】:

  • 哇,涉及到给定的示例。一方面我觉得“向编译器实现者致敬”,另一方面我想知道这种复杂性是否真的有必要,因为理解这样的代码很困难。
  • @coproc 我只是希望我永远不会在我将使用的生产代码中看到这样的代码 sn-ps :)
  • MISRA C 规则 9.2 似乎不鼓励大括号省略,但 google c++ 编码指南并未提及大括号省略。疏忽?
【解决方案2】:

是的,这是标准 C++。在聚合初始化中(在聚合初始化中,而不是在其他形式的列表初始化中),可以省略大括号,有效地扁平化聚合的包含层次结构。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多