Nehmen wir an, ich habe eine Klasse mit einem Member-Array von std::atomic
s, wobei der
Das Array wird über eine Berechnung dimensioniert (d. h. es kann sich basierend auf anderen Konstanten anderswo im Programm ändern):
Was ist der eleganteste Weg, um sicherzustellen, dass die Atomics alle initialisiert werden?
Null? Kann ich besser als das Array im Konstruktor von Foo
durchlaufen und
explizit Null speichern? Unterscheidet sich die Antwort für std::array
?
Normalerweise würde ich hier einen Klammerinitialisierer verwenden, aber die abgeleitete Länge (die kann lang sein) macht es schwierig.
Beachten Sie, dass ich nicht davon ausgehen kann, dass die Instanz von Foo
über statischen Speicher verfügt
Dauer.
Okay, ich glaube, ich habe das durchgearbeitet. Beide initialisieren alle die Atome zu Null:
%Vor%Hier ist die Logik:
[dcl.init.aggr] / 1 definiert Arrays als Aggregate.
[array.cons] / 1 verlangt, dass std::array
ebenfalls ein Aggregat ist.
[dcl.init.aggr] / 7 sagt, dass es weniger Elemente des Initialisierers gibt Liste, als es Mitglieder in der Gesamtheit gibt, dann die restlichen Mitglieder soll aus einer leeren Initialisierungsliste initialisiert werden. In diesem Fall ist das so alle Mitglieder.
[dcl.init.list] / 3 definiert Listeninitialisierung aus einer leeren Liste für eine Klasse
mit einem Standardkonstruktor (wie mit std::atomic
) zu verursachen
Wert-Initialisierung.
[dcl.init] / 7 sagt, dass Klassen ohne vom Benutzer bereitgestellte Konstruktoren sind
Null initialisiert. Angenommen, std::array<T>
enthält ein Array von T
,
und dass die Nulldarstellung von std::atomic<size_t>
das ist, was wir erwarten,
dann sind wir gut.
Nun, std::atomic
hat einen vom Benutzer bereitgestellten Konstruktor, nur keinen
Vom Benutzer bereitgestellter Standard -Konstruktor (Letzterer ist explizit voreingestellt). Damit
es passt technisch nicht zu den Bedingungen des letzten Punktes. Aber es scheint so
ist ein Fehler im Standard und wurde fixed in neuerer Zeit
Entwürfe.