Question

I'm looking for a nice solution is how to initialize a static boost::array with a custom user structure and data. My example, what I'm expecting from boost::array, below:

 struct Foo
 {
      std::string a;
      std::string b;
 };
 static boost::array< Foo, 2 > foo =
 {
      { "111", "222" },
      { "333", "444" },
 };

But this code didn't work,

error C2078: too many initializers

What I'm missing?

Thnks!

Was it helpful?

Solution

This is caused by the way brace elision works. From N3485, 8.5.1.11:

Braces can be elided in an initializer-list as follows. If the initializer-list begins with a left brace, then the succeeding comma-separated list of initializer-clauses initializes the members of a subaggregate; it is erroneous for there to be more initializer-clauses than members. If, however, the initializer-list for a subaggregate does not begin with a left brace, then only enough initializer-clauses from the list are taken to initialize the members of the subaggregate; any remaining initializer-clauses are left to initialize the next member of the aggregate of which the current subaggregate is a member.

In other words, if the next thing is an initializer-list, we can assume no brace elision has occurred. The braces are inserted at the innermost level, and so while we would like the following

{{"a", "b"}, {"c", "d"}}  -> {{{"a", "b"}, {"c", "d"}}}

we instead get

{{"a", "b"}, {"c", "d"}} -> {{{"a", "b"}}, {"c", "d"}}

Now as to why we can elide even more braces and write {"a", "b", "c", "d"}: once we hit the "a", we know that brace elision has happened, as we expect the array member to be initialised with an initializer-list. We thus start consuming as many initializer-clauses as necessary to initialize the member array. Again, we hit the "a" instead of an initializer-list, and so we start consuming as many initializer-clauses as necessary to initialize the first Foo. We repeat this for the second Foo, consume all clauses, and end up with

{"a", "b", "c", "d"} -> {{{"a", "b"}, {"c", "d"}}}

as desired.

OTHER TIPS

Adding an extra set of braces works for me.

 static boost::array< Foo, 2 > foo =
 {{
    { "111", "222" },
    { "333", "444" },
 }};

More as I figure out why. I think the key here is "brace elision" (thanks to jesyspa for pointing me there)

This also works:

 static boost::array< Foo, 2 > foo =
 {
    "111", "222",
    "333", "444",
 };
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top