Ich weiß, dass mindestens eine der Änderungen in C ++ 11 dazu führt, dass ein alter Code nicht mehr kompiliert wird: die Einführung explicit operator bool()
in die Standardbibliothek, die alte Instanzen von ersetzt operator void*()
. Zugegeben, der Code, den dies beschädigen wird, ist wahrscheinlich Code, der eigentlich nicht gültig sein sollte, aber es ist trotzdem eine wichtige Änderung: Programme, die früher gültig waren, sind es nicht mehr.
Gibt es noch andere wichtige Änderungen?
export
Schlüsselworts entfernen ? Ich hole mir Mantel.mystream.good()
ist nicht dasselbe wiebool(mystream)
?good()
ist wahr, wenn kein Flag gesetzt ist.bool(mystream)
ist immer noch falsch, wenn nureofbit
gesetzt ist.!mystream.fail()
wäre das richtige Äquivalent.Antworten:
Das FDIS enthält einen Abschnitt für Inkompatibilitäten im Anhang
C.2
"C ++ und ISO C ++ 2003".Zusammenfassung, um das FDIS hier zu paraphrasieren, damit es (besser) als SO-Antwort geeignet ist. Ich habe einige eigene Beispiele hinzugefügt, um die Unterschiede zu veranschaulichen.
Es gibt einige bibliotheksbezogene Inkompatibilitäten, bei denen ich die Auswirkungen nicht genau kenne. Daher überlasse ich diese anderen, um sie zu erläutern.
Kernsprache
(Zugegebenermaßen kein wirkliches Kompatibilitätsproblem für die meisten Menschen).
Beispiel von mir:
Solche Größen von Tricks wurden von einigen SFINAE verwendet und müssen jetzt geändert werden :)
Beispiel von mir:
Dieser Code ruft
terminate
in C ++ 0x auf, jedoch nicht in C ++ 03. Weil die implizite Ausnahmespezifikation vonA::~A
in C ++ 0x istnoexcept(true)
.In C ++ 03
>>
wäre immer das Shift-Operator-Token.Beispiel von mir:
In C ++ 03 wird dies aufgerufen
f(long)
, in C ++ 0x jedochf(int)
. Es ist zu beachten, dass sowohl in C ++ 03 als auch in C ++ 0x die folgenden Aufrufe ausgeführt werdenf(B)
(der Instanziierungskontext berücksichtigt immer noch nur externe Verknüpfungsdeklarationen).Die bessere Übereinstimmung
f(A)
wird nicht genommen, da es keine externe Verknüpfung gibt.Bibliotheksänderungen
quelle
export
, dann denke ich , die anderen TUs würde nicht auf die explizite Instanziierung verlassen müssen, konnte aber die Vorlage themselfs instanziiert. Dann würde es einen Unterschied machen, ob interne Verknüpfungsfunktionen im Instanziierungskontext sichtbar sind oder nicht.Die Bedeutung des Auto-Schlüsselworts wurde geändert.
quelle
auto
Schlüsselwort verwendet haben, stimmt etwas mit Ihrem Code nicht. Warum um alles in der Welt würdest du es benutzen?auto
bleibt in C ++ 11 gültig.int main() { auto int i = 0; return i; }
ist perfekt gültig C ++ 03, aber ein Syntaxfehler in C ++ 11. Die einzige Warnung, die Compiler im C ++ 03-Modus dazu geben können, ist eine Warnung zur Kompatibilität.Veränderung brechen?
Nun, für eine Sache, wenn man verwendet
decltype
,constexpr
,nullptr
etc. als Bezeichner dann können Sie in Schwierigkeiten ...quelle
Einige Kerninkompatibilitäten, die nicht im Abschnitt Inkompatibilitäten behandelt werden:
C ++ 0x behandelt den Namen der injizierten Klasse als Vorlage, wenn der Name als Argument an einen Vorlagenvorlagenparameter übergeben wird, und als Typ, wenn er an einen Vorlagentypparameter übergeben wird.
Gültiger C ++ 03-Code kann sich anders verhalten, wenn der Name der injizierten Klasse in diesen Szenarien immer ein Typ ist. Beispielcode aus meiner Clang-PR
In C ++ 03 ruft der Code
g
beide Male die Sekunde auf.C ++ 0x macht einige Namen, die in C ++ 03 abhängig waren, jetzt unabhängig. Außerdem muss die Namenssuche für nicht abhängige qualifizierte Namen, die sich auf Mitglieder der aktuellen Klassenvorlage beziehen, bei der Instanziierung wiederholt werden, und es muss überprüft werden, ob diese Namen auf dieselbe Weise wie im Kontext der Vorlagendefinition gesucht werden.
Gültiger C ++ 03-Code, der von der Dominanzregel abhängt, wird aufgrund dieser Änderung möglicherweise nicht mehr kompiliert.
Beispiel:
Dieser gültige C ++ 03-Code, der aufgerufen
A<int>::f
wird , ist in C ++ 0x nicht gültig, da die Namenssuche beim InstanziierenA<int>::f
im Gegensatz zu gefundenB::f
wird und einen Konflikt mit der Definitionssuche verursacht.Zu diesem Zeitpunkt ist nicht klar, ob dies ein Defekt im FDIS ist. Der Ausschuss ist sich dessen bewusst und wird die Situation bewerten.
Eine using-Deklaration, bei der der letzte Teil mit dem Bezeichner im letzten Teil des Qualifizierers im qualifizierten Namen für eine Basisklasse identisch ist. Diese using-Deklaration benennt jetzt den Konstruktor anstelle von Mitgliedern mit diesem Namen.
Beispiel:
Der obige Beispielcode ist in C ++ 03 gut geformt, in C ++ 0x jedoch schlecht geformt, da in C ++ 03
A::B
immer noch nicht darauf zugegriffen werden kannmain
.quelle
Stream-Extraktionsfehler werden unterschiedlich behandelt.
Beispiel
Vorschlag ändern
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3246.html#23
Standardreferenz
Implementierungen
GCC 4.8 gibt korrekt für C ++ 11 aus :
GCC 4.5-4.8 alle Ausgaben für C ++ 03 wie folgt, was ein Fehler zu sein scheint:
Visual C ++ 2008 Express gibt korrekt für C ++ 03 aus:
Visual C ++ 2012 Express gibt fälschlicherweise für C ++ 11 aus, was anscheinend ein Problem mit dem Implementierungsstatus darstellt:
quelle
Wie ist die Einführung expliziter Konvertierungsoperatoren eine bahnbrechende Änderung? Die alte Version ist immer noch genauso "gültig" wie zuvor.Ja, der Wechsel von
operator void*() const
zuexplicit operator bool() const
wird ein bahnbrechender Wechsel sein, aber nur, wenn er auf eine Weise verwendet wird, die an und für sich falsch ist. Konformer Code wird nicht beschädigt.Eine weitere wichtige Änderung ist das Verbot der Verengung von Conversions während der aggregierten Initialisierung :
Bearbeiten : Nur erinnern,
std::identity<T>
wird in C ++ 0x entfernt (siehe Hinweis). Es ist eine praktische Struktur, um Typen abhängig zu machen. Da die Struktur wirklich nicht viel tut, sollte dies das Problem beheben:quelle
operator void*
.bool ok = cin >> a; cout << "done reading" << endl; if (ok) { ... }
In C ++ 03 ist daran nichts wirklich Falsches, aber in C ++ 11 ist es zu einem Fehler geworden. (Hinweis: GCC 4.9 hat nochoperator void*() const
hier, weshalb es den Code im C ++ 11-Modus akzeptiert.)std::identity<T>
wurde in C ++ 11 nicht entfernt, da es nicht Teil von C ++ 03 war. Es war im Entwurf für C ++ 11 kurz vorhanden und wurde vor der Standardisierung aus dem Entwurf entfernt.Es gibt zahlreiche Änderungen an der Containerbibliothek, die effizienteren Code ermöglichen, aber die Abwärtskompatibilität für einige Eckfälle stillschweigend unterbrechen.
Betrachten Sie beispielsweise die
std::vector
Standardkonstruktion, C ++ 0x und wichtige Änderungen .quelle
Es wurde viel darüber diskutiert implizite Schritte , die die Abwärtskompatibilität beeinträchtigen
( eine ältere Seite mit relevanter Diskussion )
Wenn Sie in den Kommentaren nachlesen, ist die implizite Verschiebungsrückgabe ebenfalls eine wichtige Änderung.
quelle
C ++ 03: gültig.
C ++ 0x:
error: parameter declared 'auto'
quelle
struct x
und ohne Namen.Sprachmerkmale
>>
Komponenten der Standardbibliothek
Veraltete Funktionen
quelle