How do I initialize a member array with an initializer_list?
As far as I can tell, using list-initialization of the function argument of the constructor (8.5.4/1) should be legal and solves many of the issues of the above. However, GCC 4.5.1 on ideone.com fails to match the constructor and rejects it.
#include <array>
struct Foo
{
std::array< int, 2 > const data;
Foo(std::array<int, 2> const& ini) // parameter type specifies size = 2
: data( ini )
{}
};
Foo f( {1,3} ); // list-initialize function argument per 8.5.4/1
If you really insist on initializer_list
, you can use reinterpret_cast
to turn the underlying array of the initializer_list
into a C-style array.
Foo(std::initializer_list<int> ini) // pass without reference- or cv-qualification
: data( reinterpret_cast< std::array< int, 2 > const & >( * ini.begin() )
You can use a variadic template constructor instead of an initializer list constructor:
struct foo {
int x[2];
template <typename... T>
foo(T... ts) : x{ts...} { // note the use of brace-init-list
}
};
int main() {
foo f1(1,2); // OK
foo f2{1,2}; // Also OK
foo f3(42); // OK; x[1] zero-initialized
foo f4(1,2,3); // Error: too many initializers
foo f5(3.14); // Error: narrowing conversion not allowed
foo f6("foo"); // Error: no conversion from const char* to int
}
EDIT: If you can live without constness, another way would be to skip initialization and fill the array in the function body:
struct foo {
int x[2]; // or std::array<int, 2> x;
foo(std::initializer_list<int> il) {
std::copy(il.begin(), il.end(), x);
// or std::copy(il.begin(), il.end(), x.begin());
// or x.fill(il.begin());
}
}
This way, though, you lose the compile-time bounds checking that the former solution provides.