2013-04-17 35 views
19

jako pytanie, które pojawiły się podczas dyskusji this SO question:Czy można zadeklarować obiekt constexpr initializer_list?

Czy to jest legalne, może z N3471, aby zadeklarować constexpr std::initializer_list obiekt? Przykład:

constexpr std::initializer_list<int> my_list{}; 

Dlaczego myślę, że to nie może być legalne: initializer_list musiałby być typu dosłowny; ale czy są jakieś gwarancje, że jest to typ literalny?

Cytaty z N3485.

[dcl.constexpr]/9:

specyfikator constexpr stosowane w zgłoszenia obiektu deklaruje obiekt jako const. Taki obiekt będzie miał literał i będzie inicjowany.

dosłownych wymagania rodzaje [basic.types]/10, pod-typy klas pocisku:

  • typu klasy (Rozdział 9), który ma wszystkie z następujących właściwości:
    • ma trywialny destruktor,
    • każde wywołanie konstruktora i pełne wyrażenie w inicjatorach klamrowych lub równoważnych dla niestatycznych elementów danych (jeśli występują) jest wyrażeniem stałym (5.19),
    • jest to typ agregacyjny (8.5.1) lub ma co najmniej jeden konstruktor constexpr lub szablon konstruktora, który nie jest konstruktorem kopiowania ani przenoszenia, a wszystkie jego niestatyczne elementy danych i klasy bazowe mają wartość inną niż non-static. -wolne typy literalne.

Dodatkowe punkty za odpowiedzi;) jeśli

constexpr std::initializer_list<int> my_list = {1,2,3,4,5}; 

jest legalne (referencje). Choć myślę, że to jest objęte powyższym + [dcl.init.list]/5

+0

Powtarzam tylko to, co powiedziałem na czacie: nie mam sensu tworzyć funkcji 'std :: initializer_list'' constexpr' (N3741), jeśli nie możemy legalnie napisać ostatniego przykładu. – Morwenn

Odpowiedz

8

Aktualizacja: Sytuacja się trochę bardziej skomplikowana, po ustąpieniu CWG DR 1684 usunęła wymóg cytowanym poniżej. Niektóre Więcej informacji można znaleźć w this discussion on the std-discussion mailing list i w odpowiednim pytanie Why isn't `std::initializer_list` defined as a literal type?


[decl.constexpr]/8:

specyfikator constexpr na niestatycznych funkcji użytkownik, który nie jest konstruktor deklaruje, że funkcja member ma być const (9.3.1). [...] Klasa, której funkcją jest członek, jest typu dosłownego (3.9).

W związku z tym zmiany w gwarancji N3471 std::initializer_list będą miały charakter literalny.


Zanotować constexpr konstruktor sam nie wymaga std::initializer_list być typu dosłownym, patrz [dcl.constexpr]/4 + 8. Uwaga boczny: Przedmiotem niż dosłownym typu o constexpr ctor można zainicjować w stałej inicjalizacji [basic.start.init]/2] (części statycznego inicjalizacji, wykonywana jest przed dynamicznego inicjalizacji).

+0

Znalazłem tę odpowiedź kilka godzin po opublikowaniu pytania - zastanawiasz się, jaki użytek będzie "constexpr" w typie nie literalnym. – dyp

+0

Nie jestem pewien, aby wszystko zrozumieć - jest 'constexpr std :: initializer_list my_list = {1,2,3,4,5};' legal or not in C++ 14? – ChristopherC

+0

@ ChristopherC Przepraszamy, wydaje się, że wymaga to nowego dochodzenia: Uchwała [CWG DR 1684] (http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1684) usunęła cytowany fragment ze standardu C++ 14. Nie mogę znaleźć żadnych innych wskazówek, że 'std :: initializer_list' jest wymagany w danym momencie jako typ literalny. – dyp

Powiązane problemy