L'absence de
std::array<T,size>::array(const T& value);
un oubli? Il me semble très utile et les conteneurs dynamiques (comme std::vector
) ont un constructeur similaire.
Je suis pleinement conscient de
std::array<T,size>::fill(const T& value);
mais ce n'est pas un constructeur, et la mémoire sera mise à zéro en premier. Et si je veux tout -1
c'est comme ce mec ?
std::array
est, par conception, un agrégat, donc n'a pas de constructeurs déclarés par l'utilisateur.
Comme vous le dites, vous pouvez utiliser fill
après la construction par défaut. Puisqu'il s'agit d'un agrégat, la construction par défaut ne remettra pas à zéro la mémoire, mais la laissera non initialisée (si le type contenu est trivialement initialisable).
Notez que vous pouvez simuler efficacement ce type de constructeur en tirant parti du fait que le tableau n'est pas initialisé à zéro, et a un constructeur de copie et 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');
Tout d'abord, ce n'est pas std::array<T>
, c'est std::array<T,N>
où N
est l'expression intégrale de la constante de temps de compilation.
Seconde, std::array
est fait agrégé par conception. Il n'a donc rien qui le rend non agrégé, c'est pourquoi il n'a pas de constructeur ... ni de destructeur, de fonctions virtuelles, etc.
Vous pouvez utiliser std::index sequence
Pour cela:
namespace detail
{
template <typename T, std::size_t...Is>
constexpr 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>
constexpr std::array<T, N> make_array(const T& value)
{
return detail::make_array(value, std::make_index_sequence<N>());
}
std::make_index_sequence
Est C++ 14, mais peut être implémenté en C++ 11.
static_cast<void>(Is)
est pour gérer le mal operator,
que T
pourrait fournir.