c++嵌套聚合初始化规则

问题描述 投票:0回答:1

给出以下代码

struct B {int i[2];};
struct A {B b[2];};
int main() {
    A{{0, 0}, {0, 0}}; //too many initializers for ‘A’
    A{{0, 0}, B{0, 0}}; //too many initializers for ‘A’
    A{B{0, 0}, {0, 0}};
    A{B{0, 0}, B{0, 0}};
}

为什么前两个不能编译?我认为所有四行应该表示相同的意思,因为它们都是一对一映射?

(测试使用g++ 13.2.0 -std=c++20编译)

c++ struct nested record braced-init-list
1个回答
0
投票

比如我觉得

A{{0, 0}, {0, 0}}
没有任何歧义?

让我们看看

[dcl.init.aggr]/16
:

可以在初始化列表中省略大括号,如下所示。 如果初始化器列表以左大括号开头,则后续的以逗号分隔的初始化器子句列表将初始化子聚合的元素;初始化子句的数量多于元素的数量是错误的。 但是,如果子聚合的初始值设定项列表不以左大括号开头,则仅从列表中获取足够的初始值设定项子句来初始化子聚合的元素;任何剩余的初始化子句都用于初始化当前子聚合是其元素的聚合的下一个元素。

解析似乎如下:

  A{{0, 0}, {0, 0}}
// ^ Entering `A`
  A{{0, 0}, {0, 0}}
//  ^ Entering `b`
  A{{0, 0}, {0, 0}}
//   ^ Entering `b[0]`, the opening brace is omitted.
//   ^ Initializing `b[0].i[0]`
  A{{0, 0}, {0, 0}}
//      ^ Initializing `b[0].i[1]`
  A{{0, 0}, {0, 0}}
//       ^ Exiting `b[0]`
//       ^ Exiting `b`
  A{{0, 0}, {0, 0}}
//          ^ `A` has no more fields, expected `}`
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.