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

时间:2016-10-18 15:19:31

标签: c++ initialization initializer-list initializer stdarray

使用嵌套的支撑初始化列表初始化聚合类型(例如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>'

1 个答案:

答案 0 :(得分:2)

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

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

  

嵌套初始化程序列表周围的大括号可以省略(省略),在这种情况下,必要时使用许多初始化子句来初始化相应子集合的每个成员或元素,后续的初始化子句用于初始化以下内容对象的成员。

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