Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializer-list for initializing 2D std::array member

Tags:

c++

arrays

c++11

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

like image 651
masoud Avatar asked Nov 03 '13 18:11

masoud


People also ask

Does std :: array initialize?

std::array contains a built-in array, which can be initialized via an initializer list, which is what the inner set is. The outer set is for aggregate initialization.

What is STD initializer list in C++?

An object of type std::initializer_list<T> is a lightweight proxy object that provides access to an array of objects of type const T .

What is an array initializer list?

The initializer for an array is a comma-separated list of constant expressions enclosed in braces ( { } ). The initializer is preceded by an equal sign ( = ). You do not need to initialize all elements in an array.


2 Answers

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:

  • When can outer braces be omitted in an initializer list?
like image 105
Nawaz Avatar answered Oct 02 '22 22:10

Nawaz


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} } }
                };
like image 32
juanchopanza Avatar answered Oct 02 '22 21:10

juanchopanza