Ich habe einige Probleme bei der Kompilierung von Elementen vom Typ T in einen Vektor, wenn ich mit g ++ -std = c ++ 0x kompiliere.
Dies ist ein minimales Beispiel:
%Vor%Es kompiliert gut mit g ++ -Wall -pedantic, aber es gibt diesen Fehler beim Kompilieren mit g ++ -Wall -pedantic -std = C ++ 0x:
%Vor% So scheint es, dass es nicht den richtigen Operator = von A. Warum? Warum gibt es with _Iterator = A*
an, wenn ich A übergebe?
Die Anforderung Zuweisbar , die von den Sprachstandards für die Standardcontainerelemente übernommen wird, erfordert, dass der Ausdruck t = u
gültig ist, auch wenn u
ein konstantes Objekt ist. Die Anforderung wurde seit C ++ 98 (siehe 23.1 / 4) so definiert.
Sie haben diese Anforderung verletzt, da Ihr Zuweisungsoperator keine konstanten Objekte akzeptiert. Dies bedeutet sofort, dass Ihre Klasse A
nicht als Containerelementtyp verwendet werden kann.
Warum es in C ++ 03 funktionierte, ist ziemlich irrelevant. Es funktionierte durch Zufall. Es ist offensichtlich aus der Fehlermeldung, dass die C ++ 0x-Implementierung der Bibliothek einige C ++ 0x spezifische Features (wie std::move
) verwendet, was die obige Anforderung ins Spiel bringt. Eine C ++ 03-Implementierung (und sogar eine C ++ 98-Implementierung) kann jedoch auch nicht für Ihr A
kompilieren.
Ihr Beispiel mit A c = a;
ist irrelevant, da es den Zuweisungsoperator überhaupt nicht verwendet (warum ist es hier?).
Um den Fehler zu beheben, sollten Sie den Parameter entweder durch const Referenz oder durch Wert akzeptieren.
Ich bin mir ziemlich sicher, dass dies ein Sicherheitsmerkmal ist. Typen mit einem Kopierzuweisungsoperator (oder einem Kopierkonstruktor), die die rechte Seite mutieren können, sind nicht sicher in Standardcontainern zu verwenden - ein Beispiel dafür ist (das jetzt veraltete) std::auto_ptr
was in einem Container in einem schrecklichen Zustand bricht.
Die alte C ++ 03-Bibliotheksimplementierung erlaubte solchen unsicheren Code, aber offenbar implementierten sie eine Kompilierzeitprüfung in der C ++ 0x-Version - wahrscheinlich in Verbindung mit move - die Container aktivieren.
Die Standarddefinition des Kopierzuweisungsoperators lautet (Abschnitt [class.copy]
):
Ein benutzerdefinierter Kopier Zuweisungsoperator
X::operator=
ist eine nicht statische Nicht-Template-Memberfunktion der KlasseX
mit genau einem Parameter vom TypX
,X&
,const X&
,volatile X&
oderconst volatile X&
.
Die Varianten X&
und volatile X&
sind jedoch möglicherweise nicht mit Containern kompatibel, wenn davon ausgegangen wird, dass eine Zuweisung aus einem R-Wert RHS erfolgen kann.
HINWEIS: Weitergabe nach Wert, z. X::operator=(X)
ist ein grundlegender Teil des Copy-and-Swap-Idioms.