Ist das Fehlen von
std::array<T,size>::array(const T& value);
ein Versehen? Es scheint mir sehr nützlich zu sein, und dynamische Container (wie std::vector
) haben einen ähnlichen Konstruktor.
Ich bin mir dessen voll bewusst
std::array<T,size>::fill(const T& value);
Dies ist jedoch kein Konstruktor, und der Speicher wird zuerst auf Null gesetzt. Was ist, wenn ich will, dass alle so sind -1
wie dieser Typ ?
std::vector
). Da dies also immer gleichbedeutend wärearray(); array.fill();
, verbirgt das Weglassen des Konstruktors diese Tatsache nicht.Antworten:
std::array
ist von Natur aus ein Aggregat und hat daher keine vom Benutzer deklarierten Konstruktoren.Wie Sie sagen, können Sie
fill
nach der Standardkonstruktion verwenden. Da es sich um ein Aggregat handelt, wird der Speicher durch die Standardkonstruktion nicht auf Null gesetzt, sondern nicht initialisiert (wenn der enthaltene Typ trivial initialisierbar ist).quelle
:/
Beachten Sie, dass Sie diesen Konstruktortyp effizient simulieren können, indem Sie die Tatsache ausnutzen, dass das Array nicht mit Null initialisiert ist und über einen Kopierkonstruktor verfügt.
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');
quelle
;-)
.char
kann gefolgert werden, so können Sie einfach schreibenmake_array<20>('z')
stattmake_array<20,char>('z')
make_array
stattdessen keine gibt:-)
T
es nicht standardmäßig konstruierbar ist, und wenn Sie den Füllkonstruktor dringend benötigen.Sie können dafür verwenden
std::index sequence
: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>()); }
Demo
std::make_index_sequence
ist C ++ 14, kann aber in C ++ 11 implementiert werden.static_cast<void>(Is)
ist mit dem Bösen umzugehenoperator,
,T
das bieten könnte.quelle
T
nicht standardmäßig konstruierbar ist. In diesem Fall sind die anderen Antworten nicht ausreichend.std::index_sequence
könnte mit Logarithmus-Instanziierung anstelle von linear implementiert werden. und der Compiler verfügt möglicherweise über "Eigenheiten" , um nur eine Instanziierung durchzuführen. Dann gibt es keine Rekursion mehr.std::vector
, undreserve
ganz Größe undemplace_back
in einem loop.As für ein Million-Element, würde Stapel problematisch sein , als Speicher in der Praxis begrenzt.Erstens ist es nicht
std::array<T>
, dassstd::array<T,N>
hier derN
Integralausdruck der Kompilierungszeitkonstante ist.Zweitens
std::array
wird durch Design aggregiert. Es hat also nichts, was es nicht aggregiert, weshalb es keinen Konstruktor ... und keinen Destruktor, keine virtuellen Funktionen usw. hat.quelle