How to create std::array with initialization list without providing size directly
C++InitializationStdarrayC++ Problem Overview
How can I make a3
compile?
int main()
{
int a1[] = { 1, 2, 3 };
std::array<int, 3> a2 = { 1, 2, 3 };
std::array<int> a3 = { 1, 2, 3 };
}
It's very inconvenient, and brittle, to hard-code the size of the array when using an initialization list, especially long ones. Is there any work around? I hope so otherwise I'm disappointed because I hate C arrays and std::array
is supposed to be their replacement.
C++ Solutions
Solution 1 - C++
There is currently no way to do this without rolling your own make_array
, there is a proposal for this N3824: make_array which has the following scope:
>LWG 851 intended to provide a replacement syntax to
>
> array
It also includes a sample implementation, which is rather long so copying here is impractical but Konrad Rudolph has a simplified version here which is consistent with the sample implementation above:
template <typename... T>
constexpr auto make_array(T&&... values) ->
std::array<
typename std::decay<
typename std::common_type<T...>::type>::type,
sizeof...(T)> {
return std::array<
typename std::decay<
typename std::common_type<T...>::type>::type,
sizeof...(T)>{std::forward<T>(values)...};
}
Solution 2 - C++
You're being a little overdramatic when you say "such a horribly complex (to me) function is required". You can make a simplified version yourself, the proposal also includes a "to_array" function to convert C-arrays and deducing the type from the first parameter. If you leave that out it gets quite manageable.
template<typename T, typename... N>
auto my_make_array(N&&... args) -> std::array<T,sizeof...(args)>
{
return {std::forward<N>(args)...};
}
which you can then call like
auto arr = my_make_array<int>(1,2,3,4,5);
edit: I should mention that there actually is a version of that in the proposal that I overlooked, so this should be more correct than my version:
template <typename V, typename... T>
constexpr auto array_of(T&&... t)
-> std::array < V, sizeof...(T) >
{
return {{ std::forward<T>(t)... }};
}