7
#include <array>
using std::array;

constexpr auto d1=2;
constexpr auto d2=3;
constexpr auto d3=4;

// stacked std::array
using arr_t   = array<int,d1>;
using arr2d_t = array<arr_t,d2>;
using arr3d_t = array<arr2d_t,d3>;
constexpr arr3d_t arr1 = {{
    {{  {1,2},  {3,4},  {5,6}  }},
    {{  {1,2},  {3,4},  {5,6}  }},
    {{  {1,2},  {3,4},  {5,6}  }},
    {{  {1,2},  {3,4},  {5,6}  }}
}};

// built-in array
using carr3d_t = int[d3][d2][d1];
constexpr carr3d_t arr2 = {
    { {1,2}, {3,4}, {5,6} },
    { {1,2}, {3,4}, {5,6} },
    { {1,2}, {3,4}, {5,6} },
    { {1,2}, {3,4}, {5,6} }
};

Although, one can get away all the braces business with only pair of single braces like these:

// getaway with one-dimensional declaration
constexpr arr3d_t arr3 = {
    1,2,  3,4,  5,6,
    1,2,  3,4,  5,6,
    1,2,  3,4,  5,6,
    1,2,  3,4,  5,6
};
constexpr carr3d_t arr4 = {
    1,2,  3,4,  5,6,
    1,2,  3,4,  5,6,
    1,2,  3,4,  5,6,
    1,2,  3,4,  5,6
};

I'd like to know why {{ are required except on the lowest dimension when using stacked std::array?

godbolt.org/g/b6qfn4

sandthorn
  • 2,770
  • 1
  • 15
  • 59

2 Answers2

6

The outer braces are aggregate initializer syntax and the inner are array initializer syntax.

C++14 allows brace elision. Make sure you are compiling with C++14 or better.

Dúthomhas
  • 8,200
  • 2
  • 17
  • 39
3

Your types arr_t, arr2d_t, arr3d_t and carr3d_t are aggregate types. They are aggregate types because the std::array itself is an aggregate type. Their objects are initialized using aggregate initialization and when compiling with the C++11 support you need the (extra) {} braces surrounding the nested initializer(s). Starting with the C++14 standard:

the braces around the nested initializer lists may be elided (omitted)

Ron
  • 14,674
  • 4
  • 34
  • 47
  • I try both clang and gcc, it doesn't compile. This means they all don't opt c++14 brace elision for std::array case yet? [godbolt.org/g/YWAbHo](https://gcc.godbolt.org/g/YWAbHo) – sandthorn Dec 16 '17 at 06:16