【问题标题】:Aggregate initialization of std::array of subobjects with nested initializer lists使用嵌套初始化器列表对子对象的 std::array 进行聚合初始化
【发布时间】:2017-02-27 22:52:55
【问题描述】:

用嵌套的大括号初始化器列表初始化聚合类型(例如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>'

【问题讨论】:

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


    【解决方案1】:

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

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

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

    嵌套初始化器列表周围的大括号可以省略(省略),在这种情况下,使用尽可能多的初始化器子句来初始化相应子聚合的每个成员或元素,随后的初始化器子句用于初始化以下对象的成员。

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

    【讨论】:

    • 您能否详细说明为什么需要这样做?我认为使用大括号省略不需要额外的大括号。
    • @plasmacel std::array&lt;A, 2&gt; arr{{ 0, 1, 2, 3 }, { 4, 5, 6, 7 }}; 打破了大括号省略的规则,初始化器有2个子句,与相应子聚合的元素数不匹配,
    猜你喜欢
    • 2015-04-16
    • 2015-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-08
    • 2013-06-27
    • 1970-01-01
    • 2017-04-17
    相关资源
    最近更新 更多