Почему std :: array не имеет конструктора, который принимает значение для заполнения массива?

Это отсутствие

std::array<T,size>::array(const T& value);

недосмотр? Это кажется мне очень полезным, и динамические контейнеры (как std::vector) есть похожий конструктор.

Я полностью осознаю

std::array<T,size>::fill(const T& value);

но это не конструктор, и память сначала обнуляется. Что делать, если я хочу все -1это как этот парень?

62

Решение

std::array по своей структуре является агрегатом, поэтому не имеет объявленных пользователем конструкторов.

Как вы говорите, вы могли бы использовать fill после построения по умолчанию. Поскольку это агрегат, конструкция по умолчанию не обнуляет память, но оставляет ее неинициализированной (если содержащийся тип тривиально инициализируется).

45

Другие решения

Обратите внимание, что вы можете эффективно смоделировать этот тип конструктора, воспользовавшись тем, что массив не инициализируется нулями, имеет конструктор копирования и делает.

template <size_t N, class T>
array<T,N> make_array(const T &v) {
array<T,N> ret;
ret.fill(v);
return ret;
}

auto a = make_array<20>('z');
20

Прежде всего, это не std::array<T>, это std::array<T,N> где N является компиляцией постоянной времени интегрального выражения.

Во-вторых, std::array составляется по проекту. Так что у него нет ничего, что делает его неагрегированным, поэтому у него нет конструктора … и деструктора, виртуальных функций и т. Д.

11

Вы можете использовать std::index sequence для этого:

namespace detail
{

template <typename T, std::size_t...Is>
std::array<T, sizeof...(Is)> make_array(const T& value, std::index_sequence<Is...>)
{
return {{(static_cast<void>(Is), value)...}};
}
}

template <std::size_t N, typename T>
std::array<T, N> make_array(const T& value)
{
return detail::make_array(value, std::make_index_sequence<N>());
}

демонстрация

std::make_index_sequence это C ++ 14, но может быть реализовано в C ++ 11.

7
По вопросам рекламы [email protected]