Reputation: 1845
Assuming I have two structures
struct A
{ int x;
int y;
};
struct B
{ int count;
const A* list;
};
Now I want to initialize a compile time constant of B
s.
static const B Barray[] =
{ { 2,
{ { 7,8 }, {9,10} } // error
},
{ 1,
{ { 30,40 } } // error
},
};
The latter (of course) does not work since list
is not declared as an array. But this is the way (old) APIs are often declared.
I could work around with a helper function which is basically just a cast:
template<typename T>
constexpr static const T* make_pointer(const T (&array)[])
{
return array;
}
static const B Barray[] =
{ { 2,
make_pointer<A>({ { 7,8 }, {9,10} })
},
{ 1,
make_pointer<A>({ { 30,40 } })
}
};
But this is not that pretty. Is it possible to initialize the data structure directly without a helper function? (And, of course, without a named static constant for each A[].)
Upvotes: 1
Views: 79
Reputation: 238351
But this is not that pretty.
Not only is that not pretty, but it's pretty much useless because the lifetime of the temporary array ends immediately after the initialisation of the static array, leaving the pointer dangling.
This would work, but it's far from pretty:
static const B Barray[] =
{ { 2,
[]{static A a[] { { 7,8 }, {9,10} }; return a; }(),
},
{ 1,
[]{static A a[] { { 30,40 } }; return a; }(),
},
};
Named static arrays are probably the best option for now
For what it's worth, there is a language feature for this in C99 and later: Compound literal. Popular compilers also implement this as a language extension in C++, but there is some variation in their implementation and crucially, for example GCC compound literals are temporary rather than static in C++ and thus not applicable for this use case.
There's a proposal to standardise, so it may be an option in a future C++ standard. Edit: I think that as proposed, compound literals in C++ would not have static storage, and if that interpretation is correct, then it would not be applicable to this use case.
Upvotes: 3