std :: vector arbeitet mit Klassen, die nicht standardmäßig konstruierbar sind?

8

Ich habe an mehreren Stellen gelesen, dass std :: vector verlangt, dass das Vorlagenargument standardmäßig konstruierbar ist. Heute habe ich es gerade mit einer meiner Klassen versucht, die einen delete d Standardkonstruktor hat, und zu meiner Überraschung scheint es gut zu funktionieren (mit dem Standardkonstruktor von std :: vector). Ist dieses portable Verhalten oder ist dies ein Implementierungsdetail von gcc's STL und sollte ich annehmen, dass der Vektor sein Template-Argument als Standard-Konstrukt verwenden kann?

    
Cubic 01.08.2012, 16:04
quelle

4 Antworten

11

Die Anforderung in C ++ 03 besteht darin, dass Typen, die in einem Container gespeichert werden, CopyConstructible und Assignable sind (siehe §23.1 Containeranforderungen). In C ++ 11 sind diese Anforderungen jedoch gelockert und neigen dazu, sich auf die Operationen anzuwenden, die an dem Container ausgeführt werden. So hat eine einfache Standardkonstruktion keine Anforderungen (siehe teble 96, §23.1 in C ++ 11 Standard).

Sobald Sie versuchen, einen Vektor zu kopieren oder Elemente darin einzufügen, werden Sie die Anforderungen CopyInsertable , CopyAssignable , EmplaceConstructible , MoveInsertable , MoveAssignable etc. erfüllen

    
juanchopanza 01.08.2012, 16:13
quelle
14

Es gibt zwei vector<T> -Member, die in C ++ 11 ein Standard-Konstrukt T benötigen:

%Vor%

Nichts anderes. Wenn Sie also diese Signaturen verwenden, müssen Sie einen Standardkonstruktortyp haben, sonst nicht.

    
Howard Hinnant 01.08.2012 17:10
quelle
5

std::vector erfordert nicht unbedingt, dass sein Elementtyp standardmäßig dekonstruierbar ist.

Die ursprüngliche Spezifikation von std::vector (C ++ 98, C ++ 03) versucht niemals, ihre Elemente intern zu default-konstruieren. Alle neuen Elemente werden immer kopie-konstruiert von einem Objekt "von außen" (durch den aufrufenden Code) als Argument geliefert. Dies bedeutet, dass jedes Mal, wenn Sie default-konstruierte Elemente in Ihrem Vektor benötigen, es Ihre Seite des Codes (der Aufrufer) ist, die es standardmäßig konstruieren und an std::vector als " Original "zu kopierendes Element.

Zum Beispiel, wenn Sie so etwas in C ++ 98 machen

%Vor%

es erweitert sich tatsächlich in

%Vor%

durch den Standardargumentmechanismus. Mit anderen Worten, das default-konstruierte "originale" Element wird dem Konstruktor des Vektors durch den aufrufenden Code geliefert, der nicht intern vom Vektor erzeugt wird.

C ++ 11 hat das geändert und jetzt hat std::vector Methoden, die die Standard-Konstruktion seiner Elemente intern ausführen. Dies erfordert immer noch nicht unbedingt, dass Vektorelemente standardmäßig konstruierbar sind. Es bedeutet nur, dass Sie default-constructible-Elemente benötigen, um die spezifischen Methoden von std::vector zu verwenden.

    
AnT 01.08.2012 16:56
quelle
3

Nun, Vorlagen sind in gewisser Weise schwach typisiert. Das heißt, der fehlende Standardkonstruktor wird erst erkannt, wenn der Code die Methode, in der er verwendet wird, möglicherweise intern aufruft. Dies führt zu einem Kompilierungsfehler.

Wenn Sie jedoch nicht die Methoden verwenden, die intern den Standardkonstruktor verwenden, sind Sie "sicher". Ich weiß jedoch nicht, welches die "sichere" Teilmenge ist, und ich vermute, dass es nicht durch den Standard definiert ist. Beispiel: Vektorkopieren könnte resize verwenden, was wiederum den Standardkonstruktor verwenden könnte.

    
Vlad 01.08.2012 16:10
quelle

Tags und Links