Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

std::array of structures initializater list syntax

Consider the following C++ code:

struct My_Struct
{
  int a;
  int b;
};

Now I want to declare a constant std::array of these structures:

Option A:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

const std::array<My_Struct,2> my_array =
{
  {1,2},
  {2,3}
};

Option B:

const std::array<My_Struct,2> my_array =
{
  My_Struct(1,2),
  My_Struct(2,3)
};

Question: why does option A fail to compile and only option B compiles? What’s wrong with nested curly braces when initializing std::array?

It seems to me that compiler should have all necessary information to successfully compile option A, yet it produces "too many initializer values" error.

Meanwhile, nested curly braces work really good when initializing plain arrays:

const My_Struct my_array[] =
{
      {1,2},
      {2,3}
};

Compiler is MSVC 17.2, C++20 mode on.

I can live with option B, but I would like to learn what exactly am I failing to understand in option A in terms of C++ knowledge.

>Solution :

std::array is a class that contains an actual array. It looks something like this:

template <typename T, size_t N>
struct array
{
    T _unspecified_name[N];

    // Member functions.
};

Note that std::array has no constructors or private data members, so it is an aggregate.

When you brace-initialize a std::array you’re doing aggregate initialization of a class with one member that is itself an aggregate. Normally that would require two sets of braces:

//                       Braces for std::array
//                       │        │
//                       ▼        ▼
std::array<int, 2> arr = { {1, 2} };
//                         ▲    ▲
//                         │    │
//                         Braces for int[2] member

C++ has brace-elision rules to make this situation nicer though. You can omit the inner set of braces, and the initializers will "pass through" to underlying member objects that are themselves aggregates. In this case that’s the std::array‘s int[2] member.

This is the root of your issue. When you initialize an array of My_Struct using braces, the compiler thinks you intended the inner set of braces to initialize the std::array‘s My_Struct[] member rather than the My_Struct within. Since there are two initializers when it was expecting only one it throws an error:

//                                  Initializer for std::array
//                                  │                │
//                                  ▼                ▼
std::array<My_Struct, 2> my_array = { {1, 2}, {2, 3} };
//                                    ▲    ▲  ▲    ▲
//                                    │    │  │    │
//      Initializer for unnamed My_Struct[2]  │    │
//                                            What is this initializer for? I only have one member to initialize

To avoid this situation you just need to add another set of braces:

//                                  ┌ Initializer for std::array ┐
//                                  │                            │
//                                  ▼                            ▼
std::array<My_Struct, 2> my_array = { {     {1, 2}, {2, 3}     } };
//                                    ▲     ▲    ▲  ▲    ▲     ▲
//                                    |     │    │  │    │     │
//                                    |     |Initializers│     │
//                                    |   For array elements   │
//                                    |                        |
//                               Initializer for unnamed My_Struct[2]
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading