2013-04-17 9 views
19

come una questione che è venuto durante la discussione di this SO question:È legale dichiarare un oggetto inizializer_list di constexpr?

E 'legale, magari con N3471, per dichiarare un oggetto constexpr std::initializer_list? Esempio:

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

Perché penso che potrebbe non essere legale: initializer_list avrebbe dovuto essere un tipo letterale; ma ci sono garanzie che sia un tipo letterale?

Citazioni da N3485.

[dcl.constexpr]/9:

Un identificatore constexpr utilizzato in una dichiarazione oggetto dichiara l'oggetto come const. Tale oggetto deve avere il tipo letterale e deve essere inizializzato.

requisiti letterali tipi, [basic.types]/10, sub-proiettile tipi di classe:

  • un tipo di classe (Clausola 9), che contiene tutte le seguenti proprietà:
    • ha un distruttore banale,
    • ogni chiamata del costruttore e full-expression negli inizializzatori brace-or-equal per i membri di dati non statici (se presenti) è un'espressione costante (5.19),
    • è un tipo di aggregazione (8.5.1) o ha almeno un costruttore di constexpr o modello di costruttore che non è un costruttore di copia o spostamento e
    • tutti i suoi membri di dati non statici e le classi di base sono di non - tipi letterali volatili.

I punti di bonus;) per rispondere se

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

è legale (con i riferimenti). Anche se penso che questo è coperto da quanto detto sopra + [dcl.init.list]/5

+0

Solo per ripetere quello che ho detto nella chat: non ho davvero il merito di fare 'std :: initializer_list' funzioni' constexpr' (N3741) se non possiamo legalmente scrivere l'ultimo esempio. – Morwenn

risposta

8

Update: La situazione è un po 'più complicata dopo la risoluzione del CWG DR 1684 rimosso il requisito citato qui di seguito. Qualche informazione in più può essere trovato in this discussion on the std-discussion mailing list e nella relativa domanda Why isn't `std::initializer_list` defined as a literal type?


[decl.constexpr]/8:

Un identificatore constexpr per una funzione di membro non statica, che non è un costruttore dichiara che la funzione membro deve essere const (9.3.1). [...] La classe di cui tale funzione è membro deve essere di tipo letterale (3.9).

Pertanto, le modifiche di N3471 garantiscono std::initializer_list di tipo letterale.


Annotare il ctor constexpr da sola non richiede std::initializer_list essere un tipo letterale, vedi [dcl.constexpr]/4 + 8. Nota a margine: Un oggetto di tipo non letterale con constexpr ctor può essere inizializzato durante costante inizializzazione [basic.start.init]/2] (parte inizializzazione statico, eseguita prima di qualsiasi inizializzazione dinamica).

+0

Ho trovato questa risposta alcune ore dopo aver postato la domanda - chiedendomi quale uso sarebbe un 'constexpr'ctor in un tipo non letterale. – dyp

+0

Non sono sicuro di capire tutto-è 'constexpr std :: initializer_list my_list = {1,2,3,4,5};' legale o no in C++ 14? – ChristopherC

+0

@ChristopherC Siamo spiacenti, sembra che ciò richieda una nuova indagine: la risoluzione di [CWG DR 1684] (http://open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1684) ha rimosso il passaggio citato dallo standard C++ 14. Non riesco a trovare nessun altro suggerimento che 'std :: initializer_list' sia necessario per essere un tipo letterale al momento. – dyp

Problemi correlati