7

How to initialize a nested (2D) std::array via an initializer-list?

template <std::size_t W, std::size_t H> class Block { std::array<std::array<int, W>, H> block; public: template <typename ...E> Block(E&&...e) : block {{std::forward<E>(e)...}} {} }; 

The class Block should able to initialize block member as below:

Block<3, 2> b {{ {1, 2, 3}, {4, 5, 6} }}; 

Note: We have the ability to initialize the std::array directly in C++11:

std::array<std::array<int, 3>, 2> b {{ {1, 2, 3}, {4, 5, 6} }}; 

I'm using gcc-4.9.0

2
  • By making block private and providing a ctor, Block now isn't an aggregate any more. As braced-initializers are never deduced from, the only valid initialized for an object of type Block<3,2> now is Block<3,2> b {1,2,3,4,5,6} Commented Nov 3, 2013 at 21:56
  • Roll this back to the revision that makes sense for the answers, then ask a new question. Commented Nov 12, 2013 at 3:39

2 Answers 2

6

The rules for braces are very complicated when it comes to nested structures.

The simplest form in your code would be this:

Block<3, 2> b {1, 2, 3, 4, 5, 6}; 

That basically omits all the inner braces — these omissions are allowed by the language.

The next syntax, which is slightly complex, is this:

Block<3, 2> b {{1, 2, 3, 4, 5, 6}}; 

It still omits braces, but as far as Block and as its member is concerned it is FULLY braced. It omits braces for the array and its members.

And this one is FULLY braced:

Block<3, 2> b {{{ {{1, 2,3}}, {{4,5,6}} }}}; 

It braces for all inner structures.

All forms compiles fine.

See my other answer for detailed explanation:

Sign up to request clarification or add additional context in comments.

Comments

1

It may be to do with the interpretation of the standard being overly capricious with the number of braces required to initialize std::array. This fully braced version compiles without issues on GCC 4.8.1:

Block<3, 2> b { { { { {1, 2, 3} }, { {4, 5, 6} } } } }; 

Strangely, this version compiles too:

 Block<3, 2> b { {{ {1, 2, 3}, {4, 5, 6} } } }; 

1 Comment

@MM. No problem. It still doesn't make any sense to me. Anyway, I think your first attempt should be legal in C++14.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.