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


отсутствие

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

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

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

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

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

4 59

4 ответа:

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

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

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

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');

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

второе, std::array выполнена с общим дизайном. Поэтому у него нет ничего, что делает его неагрегатным, поэтому у него нет конструктора... и деструкторы, виртуальные функции и т. д.

вы можете использовать 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.