2017-02-06 1 views

Antwort

3

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.

3

Ist das obige Programm garantiert, 0 in C++ 14 zurückzugeben? Warum?

Ja. Von [vector.capacity]:

void resize(size_type sz);
13 Effekte: Wenn sz < size(), löscht die letzten size() - sz Elemente aus der Sequenz. Andernfalls werden standardmäßig Elemente in die Sequenz eingefügt.

wo von [container.requirements.general]:

Ein Element ist Xdefault- eingefügt, wenn es allocator_traits<A>::construct(m, p) durch Auswertung des Ausdrucks initialisiert wird, wo p ist die Adresse der nicht initialisierter Speicher für das Element, das innerhalb von X 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:

  1. Ändern Sie den Allocator. Stellen Sie Ihren eigenen Zuordnertyp bereit, der zwei Überladungen für construct aufweist: eine leere (die Standardinitialisierung durchführen würde) und eine, die Args&&... nimmt.
  2. Ändern Sie den Typ. Fügen Sie S einen Standardkonstruktor hinzu, der keine Initialisierung ausführt.
Verwandte Themen