代码之家  ›  专栏  ›  技术社区  ›  Peter Mitrano

为什么不能用两层列表初始值设定项来初始化2D std::数组?

  •  9
  • Peter Mitrano  · 技术社区  · 6 年前

    有人能帮我理解为什么我的编译器不能/不能推导出这个吗?(使用g++7.3)

    #include <array>
    std::array<std::array<double,2>,2> f() {
     return {{0,0},{0,0}};
    }
    

    工作正常:

    #include <array>
    std::array<std::array<double,2>,2> f() {
     return {std::array<double,2>{0,0},{0,0}};
    }
    

    #include <array>
    std::array<std::array<double,2>,2> f() {
     return std::array<std::array<double,2>,2>{{0,0},{0,0}};
    }
    

    #include <array>
    std::array<std::array<double,2>,2> f() {
     return {{{0,0},{0,0}}};
    }
    

    它使用聚合初始化,因为 std::array 没有brace init list的构造函数。那很好,但是为什么/怎么做?

    std::array<double,2> x{1,2};
    

    1 回复  |  直到 6 年前
        1
  •  7
  •   xskxzr    6 年前

    容器 std::array 相当于一个包含C数组的结构(一个实现不能实现 std::数组

    #include <array>
    std::array<std::array<double,2>,2> f() {
       return {{{{0,0}},{{0,0}}}};
    } 
    

    当然,初始值设定项列表中的大括号可以省略,就像我们通常对2D数组所做的那样:

    int arr[2][2] = {0,1,2,3};
    

    ... 但是在省略之前以省略大括号开始的初始值设定项列表不应该在省略之后以左大括号开始。换句话说,如果一个初始值设定项列表以左大括号开始,编译器将不会考虑这个初始值设定项列表省略了最外层大括号的可能性。

    在初始值设定项中 {{0,0},{0,0}} {0,0},{0,0}

    {std::array<double,2>{0,0},{0,0}} ,子初始值设定项 std::array<double,2>{0,0},{0,0} 不以左大括号开头,因此可以使用它初始化C数组的元素,这是正常的(递归地, {0,0} 是否可以初始化 std::array<double,2> 因为子初始值设定项 0,0 不以左大括号开头)。


    #include <array>
    std::array<std::array<double,2>,2> f() {
       return {0,0,0,0};
    }