Инициализация std::array с постоянным значением
Мне нужно инициализировать все элементы std::array
постоянным значением, как это можно сделать с помощью std::vector
.
#include <vector>
#include <array>
int main()
{
std::vector<int> v(10, 7); // OK
std::array<int, 10> a(7); // does not compile, pretty frustrating
}
Есть ли способ сделать это элегантно?
Прямо сейчас я использую это:
std::array<int, 10> a;
for (auto & v : a)
v = 7;
но я бы хотел избежать использования явного кода для инициализации.
Ответы
Ответ 1
С std::index_sequence
вы можете сделать:
namespace detail
{
template <typename T, std::size_t ... Is>
constexpr std::array<T, sizeof...(Is)>
create_array(T value, std::index_sequence<Is...>)
{
// cast Is to void to remove the warning: unused value
return {{(static_cast<void>(Is), value)...}};
}
}
template <std::size_t N, typename T>
constexpr std::array<T, N> create_array(const T& value)
{
return detail::create_array(value, std::make_index_sequence<N>());
}
с использованием
auto a = create_array<10 /*, int*/>(7); // auto is std::array<int, 10>
Которые, в отличие от решения std::fill
, обрабатывают неконструктивный тип по умолчанию.
Ответ 2
Увы нет; std::array
поддерживает агрегатную инициализацию, но этого недостаточно.
К счастью, вы можете использовать std::fill
или даже std::array<T,N>::fill
, что из С++ 20 элегантно, поскольку последнее становится constexpr
.
Ссылка: https://en.cppreference.com/w/cpp/container/array/fill
Ответ 3
Вы можете сделать следующее
std::array<int, 10> a;
a.fill(2/*or any other value*/);
Или используйте std::fill
из заголовочного файла алгоритмов.
Для включения файла заголовка алгоритмов используйте
#include <algorithm>
Ответ 4
Начиная с С++ 17 вы можете написать функцию constexpr для эффективной настройки массива, поскольку средства доступа к элементам теперь являются constexpr. Этот метод также будет работать для различных других схем установки начальных значений:
#include <array>
template<typename T, size_t N>
constexpr auto make_array(T value) -> std::array<T, N>
{
std::array<T, N> a{};
for (auto& x : a)
x = value;
return a;
}
int main()
{
auto arr = make_array<int, 10>(7);
}
Ответ 5
Тип std::array
- это агрегат, который поддерживает инициализацию списка:
std::array<int, 10> a{2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
Он также поддерживает агрегатную инициализацию:
std::array<int, 10> a = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
Это неудобно и подвержено ошибкам для длинных массивов, и для них было бы лучше использовать решение, подобное Jarod42s.