On 2015–09–03, at 9:11 AM, jgot...@gmail.com wrote:With the improvements from C++11 (defaulted functions, initializer-lists, and loosened POD rules) is there any reason why std::array should still be an aggregate?
It is difficult to initialize a C-style array from an initializer_list.
template <typename T, std::size_t N>
struct array {
private:
T arr_[N];
// Not default constructible. Requires that ilist covers every element.
template <std::size_t... indices>
constexpr array(std::bool_constant<false>, std::index_sequence<indices...>, std::initializer_list<T> ilist)
: arr_{ilist.begin()[indices]...}
{}
template <std::size_t... indices>
constexpr array(std::bool_constant<true>, std::index_sequence<indices...>, std::initializer_list<T> ilist)
: arr_{indices>=ilist.end()-ilist.begin()? static_cast<T const&>(T{}) : ilist.begin()[indices]...}
{}
public:
constexpr array(std::initializer_list<T> ilist)
: array(std::is_default_constructible<T>{}, std::make_index_sequence<N>{},
ilist.end()-ilist.begin() >= N*(not std::is_default_constructible<T>{})?
ilist : throw std::length_error("") ) {}
constexpr array() = default;
};
template <typename T, std::size_t N>
struct array {
private:
T arr_[N];
template <std::size_t... indices>
constexpr array(std::index_sequence<indices...>, T (&&arr)[sizeof...(indices)])
: arr_{std::move(arr[indices])...}
{}
public:
template <std::size_t M>
constexpr array(T (&&arr)[M])
: array(std::make_index_sequence<M>{}, std::move(arr)) {}
constexpr array() = default;
};
Note that given constructors, the classic initialization syntax with doubled braces will still work, but it will require an accessible element move constructor.