Reputation: 12391
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!
Upvotes: 1
Views: 793
Reputation: 3471
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.
Upvotes: 4
Reputation: 16700
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",
};
Upvotes: 2