使用嵌套初始化列表聚合初始化 std::array 个子对象

Aggregate initialization of std::array of subobjects with nested initializer lists

用嵌套的大括号初始化器列表初始化聚合类型(例如 std::array)及其子对象的正确方法是什么?我不想直接调用子类型的构造函数。

这是一个反复出现的问题,我总是对下面的代码不起作用感到惊讶,因为指定了元素的类型,因此编译器可以推导出正确的构造函数。

请注意,示例类型 A 不一定是聚合(但当然它必须支持花括号初始化列表)。

#include <array>    

struct A
{
    int values[4];
};

int main()
{
    std::array<A, 2> arr{{ 0, 1, 2, 3 }, { 4, 5, 6, 7 }};

    // Works only if A is an aggregate, also looks confusing, I don't want to do this
    //std::array<A, 2> arr{ 0, 1, 2, 3, 4, 5, 6, 7 };

    // I don't want to do this neither
    //std::array<A, 2> arr{A{ 0, 1, 2, 3 }, A{ 4, 5, 6, 7 }};

    return 0;
}

但我得到的只是错误

error: too many initializers for 'std::array<A, 2ul>'

您可以在子对象的初始化周围添加大括号,例如

std::array<A, 2> arr{{{ 0, 1, 2, 3 }, { 4, 5, 6, 7 }}};

std::array<A, 2> arr{{ 0, 1, 2, 3 }, { 4, 5, 6, 7 }}; 不起作用,因为对于 brace elision

the braces around the nested initializer lists may be elided (omitted), in which case as many initializer clauses as necessary are used to initialize every member or element of the corresponding subaggregate, and the subsequent initializer clauses are used to initialize the following members of the object.

请注意,第一个初始化子句 { 0, 1, 2, 3 } 可用于 std::array 的整个内部数组的初始化(其余元素将被初始化为零)。那么{ 4, 5, 6, 7}就变成了多余的子句。