C ++ 11 umożliwia inicjalizację w klasie elementów niestatycznych i stałych. Co się zmieniło?

Przed C ++ 11, mogliśmy wykonywać tylko inicjalizację w klasie na statycznych elementach stałych typu integralnego lub wyliczeniowego.Stroustrup omawia to w swoim C ++ FAQ, podając następujący przykład:

class Y {
  const int c3 = 7;           // error: not static
  static int c4 = 7;          // error: not const
  static const float c5 = 7;  // error: not integral
};

I następujące rozumowanie:

Dlaczego więc istnieją te niewygodne ograniczenia? Klasa jest zazwyczaj deklarowana w pliku nagłówkowym, a plik nagłówkowy jest zazwyczaj dołączany do wielu jednostek tłumaczeniowych. Jednak, aby uniknąć skomplikowanych reguł linkera, C ++ wymaga, aby każdy obiekt miał unikalną definicję. Ta zasada zostałaby zerwana, gdyby C ++ zezwalał w klasie na definiowanie obiektów, które musiały być przechowywane w pamięci jako obiekty.

Jednak C ++ 11 rozluźnia te ograniczenia, umożliwiając inicjalizację w klasie nie statycznych elementów (§ 12.6.2 / 8):

W konstruktorze bez delegowania, jeśli dany nie statyczny element danych lub klasa bazowa nie jest oznaczony przezmem-initializer-id (w tym przypadek, w którym nie malista-inicjalizatora mem ponieważ konstruktor nie mactor-initializer), a następnie obiekt nie jest wirtualną klasą bazową klasy abstrakcyjnej (10.4)

jeśli encja jest nie statycznym elementem danych, który mabrace-or-equal-initializer, jednostka jest inicjowana zgodnie z 8.5;w przeciwnym razie, jeśli encja jest elementem wariantowym (9.5), nie jest przeprowadzana inicjalizacja;w przeciwnym razie obiekt jest inicjowany domyślnie (8.5).

Sekcja 9.4.2 umożliwia również inicjowanie w klasie niestałych elementów statycznych, jeśli są one oznaczone symbolemconstexpr specyficzny.

Więc co stało się z przyczynami ograniczeń, które mieliśmy w C ++ 03? Czy po prostu akceptujemy „skomplikowane reguły linkera” lub czy coś innego się zmieniło, co ułatwia wdrożenie?

questionAnswers(3)

yourAnswerToTheQuestion