J'ai besoin d'initialiser tous les éléments d'un std::array
avec une valeur constante, comme cela peut être fait avec 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
}
Existe-t-il un moyen de le faire avec élégance?
En ce moment j'utilise ceci:
std::array<int, 10> a;
for (auto & v : a)
v = 7;
mais je voudrais éviter d'utiliser du code explicite pour l'initialisation.
Avec std::index_sequence
, vous pourriez faire:
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>());
}
Avec usage
auto a = create_array<10 /*, int*/>(7); // auto is std::array<int, 10>
Ce qui, contrairement à std::fill
solution, gère le type constructible non par défaut.
Hélas non; std::array
supporte l'initialisation globale mais cela ne suffit pas ici.
Heureusement, vous pouvez utiliser std::fill
, ou même std::array<T,N>::fill
, qui, à partir de C++ 20 est élégant car ce dernier devient constexpr
.
Référence: https://en.cppreference.com/w/cpp/container/array/fill
Vous pouvez faire comme suit
std::array<int, 10> a;
a.fill(2/*or any other value*/);
Ou utiliser std::fill
du fichier d'en-tête des algorithmes. Pour inclure le fichier d'en-tête des algorithmes, utilisez
#include <algorithm>
Depuis C++ 17, vous pouvez écrire une fonction constexpr pour configurer efficacement le tableau, car les accesseurs d'éléments sont maintenant constexpr. Cette méthode fonctionnera également pour divers autres schémas de configuration des valeurs initiales:
#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);
}
Le std::array
type est un agrégat qui prend en charge l'initialisation de liste:
std::array<int, 10> a{2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
Il prend également en charge l'initialisation agrégée:
std::array<int, 10> a = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
C'est gênant et sujet aux erreurs pour les longues baies, et vous feriez mieux d'utiliser une solution comme Jarod42 pour celles-ci.