#include <vector>
struct S { int x; };
std::vector<S> v;
int main() { v.resize(1000); return v[42].x; }
Ist das obige Programm garantiert 0 in C++ 14 zurückgeben? Warum?Container der Struktur, die primitiven Typ enthält, Null initialisiert?
#include <vector>
struct S { int x; };
std::vector<S> v;
int main() { v.resize(1000); return v[42].x; }
Ist das obige Programm garantiert 0 in C++ 14 zurückgeben? Warum?Container der Struktur, die primitiven Typ enthält, Null initialisiert?
Ja, weil std::vector::resize
und ähnliche Methoden Wert Initialisierung † standardmäßig durchführen, die wiederum die Mitglieder der Aggregate-Wert initialisiert:
Von cppr:
Die Auswirkungen des Wert der Initialisierung ist:
[...]
wenn T ein Klassentyp mit einem Standardkonstruktor ist, der weder vom Benutzer bereitgestellt noch gelöscht wird (dh, es kann sich um eine Klasse mit implizit definierten oder defaulted handeln d Standardkonstruktor), das Objekt wird auf Null initialisiert und dann wird es standardmäßig initialisiert, wenn es einen nicht-trivialen Standardkonstruktor hat;
und der Zero Initialiation Teil tut, was wir brauchen:
Wenn T eine nicht gewerkschaftlich Klassentyp ist, werden alle Basisklassen und nicht-statische Datenelemente sind Null initialisiert, und alle padding initialisiert zu Null Bits. Die Konstruktoren, falls vorhanden, werden ignoriert.
Und natürlich Null Initialisierung unseres Mitglieds das Richtige tut:
Wenn T ein Skalar-Typ ist, der Anfangswert des Objekts ist die integrale Konstante Null explizit T. umgewandelt
† Der Standard Allocator ist, kann benutzerdefinierte Verteilern unterschiedliche Initialisierung verwenden. Sie können diese verwenden, um solche Werte zu vereinigen, siehe den vollständigen Artikel auf default-insert.
Ist das obige Programm garantiert, 0 in C++ 14 zurückzugeben? Warum?
Ja. Von [vector.capacity]:
void resize(size_type sz);
13 Effekte: Wennsz < size()
, löscht die letztensize() - sz
Elemente aus der Sequenz. Andernfalls werden standardmäßig Elemente in die Sequenz eingefügt.
wo von [container.requirements.general]:
Ein Element ist
X
default- eingefügt, wenn esallocator_traits<A>::construct(m, p)
durch Auswertung des Ausdrucks initialisiert wird, wop
ist die Adresse der nicht initialisierter Speicher für das Element, das innerhalb vonX
zugewiesen wurde.
construct
für std::allocator<T>
tut, von [default.allocator]:
template <class U, class... Args> void construct(U* p, Args&&... args);
Effekte:
::new((void *)p) U(std::forward<Args>(args)...)
So, das Wert-Initialisierung. Wir machen new S()
, nicht new S
, so dass das Element x
Null initialisiert wird.
Die Wege dieses Verhalten zu vermeiden (falls gewünscht) sind entweder:
construct
aufweist: eine leere (die Standardinitialisierung durchführen würde) und eine, die Args&&...
nimmt.S
einen Standardkonstruktor hinzu, der keine Initialisierung ausführt.
Mögliche Duplikat [Initialisieren alle Doppel in einer Klasse auf Null] (http://stackoverflow.com/questions/42010793/initializing-all-doubles-in-a-class-to-zero) – SU3