2015-10-18 28 views
9

ho cercato di trasmettere-dichiarare una mascherina constexpr variabile in questo modo:Forward dichiarare un modello variabile constexpr

template<typename> 
constexpr std::size_t iterator_category_value; 

L'obiettivo era quello di documentare che ogni specializzazione dovrebbe essere constexpr, ma devo ammettere che non ho mai controllato se era legale o no e g ++ ne era felice. Tuttavia, quando ho provato a compilare questo Spinnet con clangore ++, invece, ho ottenuto il seguente errore:

error: default initialization of an object of const type 'const std::size_t' (aka 'const unsigned long') 
    constexpr std::size_t iterator_category_value; 
         ^
                = 0 

L'errore ha un senso, e la rimozione constexpr fa scomparire, così che non è un problema reale. Tuttavia, sono curioso ora: lo standard consente una tale dichiarazione anticipata constexpr per un modello variabile o è illegale? g ++ e clang ++ sembrano essere in disaccordo e mi piacerebbe sapere dove dovrei inviare una segnalazione di bug, se necessario.

Entrambi si lamentano per una variabile dichiarata inoltrata constepxr che non è un modello variabile, quindi il contesto del modello variabile sembra essere ciò che rende i compilatori in disaccordo.

+0

Il testo di http://wg21.cmeerw.net/cwg/issue1712 implica che non è possibile inoltrarlo come "constexpr", tuttavia non sono sicuro di come lo std lo proibisca. Un modello variabile non mi sembra una * dichiarazione oggetto *. – dyp

+0

OTOH, [dcl.dcl] p9 sembra molto generico e dovrebbe applicarsi ai modelli variabili (=> i modelli variabili sono dichiarazioni oggetto => 'constexpr' richiede l'inizializzazione) – dyp

+0

@dyp Btw., Cosa intendi con" ora "? Non stai compilando le fonti più aggiornate attualmente disponibili su Git? – Columbo

risposta

8

Nello standard C++ 14, sembra abbastanza chiaro che è necessaria l'inizializzazione. Dalla sezione 7.5.1 comma 9,

A constexpr specifier used in an object declaration declares the object as const. Such an object shall have literal type and shall be initialized.

Per quanto riguarda l'esatto significato di "dichiarazione oggetto", sezione 7 comma 7 stati:

If the decl-specifier-seq contains no typedef specifier, the declaration is called a function declaration if the type associated with the name is a function type and an object declaration otherwise.

8

Clang è corretta. Il dichiarazione di un modello variabile è una dichiarazione oggetto ([dcl.dcl]/9), quindi deve fornire un inizializzatore come per [dcl.constexpr]/9:

A constexpr specifier used in an object declaration declares the object as const . Such an object […] shall be initialized.

v'è effettivamente alcun modo di "inoltrare", tuttavia, dichiarare un oggetto come constexpr; Se constexpr viene applicato alla dichiarazione di una variabile, deve essere una definizione ([dcl.constexpr]/1).

+0

[Qualcosa è cambiato ultimamente?] (Http: // coliru. stacked-crooked.com/a/cb1d8ebe90a2bc11) – Orient

+0

Solo un codice contenente un caso discusso. Contiene la dichiarazione anticipata del modello di variabile 'constexpr', ma compila bene. – Orient

+0

@Orient Ti rendi conto che stai compilando il compilatore con bug in questo senso? – Columbo

Problemi correlati