Wiem, że przynajmniej jedna ze zmian w C ++ 11, która spowoduje, że jakiś stary kod przestanie się kompilować: wprowadzenie explicit operator bool()
do standardowej biblioteki, zastępujące stare instancje operator void*()
. To prawda, że kod, który to zepsuje, jest prawdopodobnie kodem, który nie powinien był być poprawny, ale nadal jest przełomową zmianą: programy, które kiedyś były prawidłowe, już nie są.
Czy są jakieś inne przełomowe zmiany?
export
słowa kluczowego? Zdobędę płaszcz.mystream.good()
to nie to samo cobool(mystream)
?good()
jest prawdziwe, jeśli nie ustawiono żadnej flagi.bool(mystream)
jest nadal fałszywe, jeśli tylkoeofbit
jest ustawione.!mystream.fail()
byłby prawidłowym odpowiednikiem.Odpowiedzi:
FDIS zawiera sekcję dotyczącą niezgodności w dodatku
C.2
„C ++ i ISO C ++ 2003”.Podsumowanie, parafrazując tutaj FDIS, aby uczynić go (lepszym) odpowiednim jako odpowiedź SO. Dodałem kilka własnych przykładów, aby zilustrować różnice.
Istnieje kilka niezgodności związanych z biblioteką, w których nie znam dokładnie konsekwencji, więc pozostawiam je innym do rozwinięcia.
Podstawowy język
(co prawda nie jest tak naprawdę problemem kompatybilności dla większości ludzi).
Przykład mojego autorstwa:
Taki rozmiar sztuczek był używany przez niektóre SFINAE i należy go teraz zmienić :)
Przykład mojego autorstwa:
Ten kod wywołuje
terminate
w C ++ 0x, ale nie w C ++ 03. Ponieważ niejawna specyfikacja wyjątkuA::~A
w C ++ 0x tonoexcept(true)
.W C ++ 03
>>
zawsze będzie tokenem shift-operator.Przykład mojego autorstwa:
W C ++ 03 to wywołuje
f(long)
, ale w C ++ 0x to wywołujef(int)
. Należy zauważyć, że zarówno w C ++ 03, jak i C ++ 0x następujące wywołaniaf(B)
(kontekst tworzenia instancji nadal uwzględnia tylko deklaracje powiązań zewnętrznych).Lepsze dopasowanie
f(A)
nie jest podejmowane, ponieważ nie ma powiązania zewnętrznego.Zmiany w bibliotece
źródło
export
, to sądzę, że inne jednostki językowe nie musiałyby polegać na jawnej instancji, ale same mogłyby utworzyć instancję szablonu. Wtedy miałoby to znaczenie, czy wewnętrzne funkcje łączenia są widoczne w kontekście tworzenia.Znaczenie słowa kluczowego auto uległo zmianie.
źródło
auto
słowa kluczowego, coś jest bardzo nie tak z twoim kodem. Dlaczego do licha miałbyś go używać?auto
pozostaje ważne w C ++ 11.int main() { auto int i = 0; return i; }
jest całkowicie poprawny w C ++ 03, ale błąd składniowy w C ++ 11. Jedynym ostrzeżeniem, które mogę uzyskać od kompilatorów w trybie C ++ 03, jest ostrzeżenie o zgodności.Łamać zmiany?
Cóż, z jednej strony, jeśli jest używana
decltype
,constexpr
,nullptr
, itd. Jako identyfikatory wtedy może mieć kłopoty ...źródło
Niektóre podstawowe niezgodności, które nie są objęte sekcją dotyczącą niezgodności:
C ++ 0x traktuje nazwę wstrzykniętej klasy jako szablon, jeśli nazwa jest przekazywana jako argument parametru szablonu szablonu i jako typ, jeśli jest przekazywana do parametru typu szablonu.
Poprawny kod C ++ 03 może zachowywać się inaczej, jeśli opiera się na wstrzykiwanej nazwie klasy, aby zawsze był typem w tych scenariuszach. Przykładowy kod zaczerpnięty z mojego clang PR
W C ++ 03 kod wywołuje drugi za
g
każdym razem.C ++ 0x sprawia, że niektóre nazwy zależne w C ++ 03 są teraz niezależne. I wymaga wyszukiwania nazw dla niezależnych nazw kwalifikowanych, które odnoszą się do członków bieżącego szablonu klasy, które muszą być powtarzane przy tworzeniu, i wymaga sprawdzenia, czy te nazwy wyszukują w taki sam sposób, jak w kontekście definicji szablonu.
Prawidłowy kod C ++ 03, który zależy od reguły dominacji, może teraz nie być kompilowany z powodu tej zmiany.
Przykład:
Ten poprawny kod C ++ 03, który wywołuje,
A<int>::f
nie jest poprawny w C ++ 0x, ponieważ wyszukiwanie nazw podczas tworzenia instancji zostanie znalezioneA<int>::f
w przeciwieństwie doB::f
, co powoduje konflikt z wyszukiwaniem w definicji.W tym momencie nie jest jasne, czy jest to wada FDIS. Komitet jest tego świadomy i oceni sytuację.
Deklaracja za pomocą, w której ostatnia część jest taka sama jak identyfikator w ostatniej części kwalifikatora w nazwie kwalifikowanej oznaczającej klasę podstawową, która za pomocą deklaracji nazywa teraz konstruktor, a nie członków o tej nazwie.
Przykład:
Powyższy przykładowy kod jest dobrze sformułowany w C ++ 03, ale źle sformułowany w C ++ 0x, ponieważ
A::B
nadal jest niedostępnymain
.źródło
Błąd ekstrakcji strumienia jest traktowany inaczej.
Przykład
Zmień propozycję
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3246.html#23
Standardowe odniesienie
Realizacje
GCC 4.8 poprawnie wyprowadza dla C ++ 11 :
GCC 4.5-4.8 wszystkie dane wyjściowe dla C ++ 03 następujące, które wydają się być błędem:
Visual C ++ 2008 Express poprawnie wyświetla dane wyjściowe dla C ++ 03:
Visual C ++ 2012 Express niepoprawnie wyświetla dane wyjściowe dla C ++ 11, co wydaje się być problemem związanym ze statusem wdrożenia:
źródło
W jaki sposób wprowadzenie jawnych operatorów konwersji jest przełomową zmianą? Stara wersja nadal będzie tak samo „ważna” jak poprzednio.Tak, zmiana z
operator void*() const
naexplicit operator bool() const
będzie przełomową, ale tylko jeśli zostanie użyta w sposób, który jest niewłaściwy sam w sobie. Zgodny kod nie zostanie uszkodzony.Kolejną przełomową zmianą jest zakaz zawężania konwersji podczas inicjalizacji zbiorczej :
Edycja : Tylko pamięć,
std::identity<T>
zostanie usunięty w C ++ 0x (patrz uwaga). Struktura wygody pozwala uzależnić typy. Ponieważ struct naprawdę niewiele robi, powinno to naprawić:źródło
operator void*
.bool ok = cin >> a; cout << "done reading" << endl; if (ok) { ... }
Nie ma w tym nic złego w C ++ 03, ale stał się błędem w C ++ 11. (Uwaga: GCC 4.9 wciążoperator void*() const
tu jest, dlatego akceptuje kod w trybie C ++ 11.)std::identity<T>
nie został usunięty w C ++ 11, ponieważ nie był częścią C ++ 03. Krótko istniał w projekcie dla C ++ 11 i został usunięty z projektu przed standaryzacją.Istnieje wiele zmian w bibliotece kontenerów, które pozwalają na bardziej wydajny kod, ale cicho przerywają kompatybilność wsteczną dla kilku przypadków narożnych.
Rozważmy na przykład
std::vector
domyślną konstrukcję, C ++ 0x i przełamywanie zmian .źródło
Było wiele dyskusji na temat niejawnego łamania kompatybilności wstecznej
( starsza strona z odpowiednią dyskusją )
Jeśli przeczytasz w komentarzach, niejawny zwrot ruchu jest również przełomową zmianą.
źródło
C ++ 03: poprawny.
C ++ 0x:
error: parameter declared 'auto'
źródło
struct x
i bez nazwy.Funkcje językowe
>>
Komponenty biblioteki standardowej
Przestarzałe funkcje
źródło