2016-07-15 95 views
6

Il seguente codice utilizza il membro enum m come espressione costante, ovvero come parametro del modello. Il codice viene compilato in gcc ma non in clang (live demo). Clang dice "errore: l'argomento modello non di tipo non è un'espressione costante".Uso di un enum come espressione costante. Quale compilatore ha ragione?

Il problema può essere risolto scambiando la linea // 1 entro il A<tst<p>::m> a. Pertanto, la mia domanda non è come risolvere questo problema, ma quale compilatore ha ragione.

template<size_t n> struct A{}; 

template<size_t n> 
struct tst 
{ enum : size_t { m= n % 15 }; 

    template<size_t p> 
    void 
    call(tst<p> const &t2) { 
     A<t2.m> a; // 1 
    } 
}; 
+0

[Questi riferimenti dicono] (http://en.cppreference.com/w/cpp/language/enum) "Quando un'enumerazione senza ambito è un membro della classe, è possibile accedere ai relativi enumeratori utilizzando gli operatori di accesso dei membri della classe' .' e '->' ". Tuttavia non parla di essere espressioni costanti. –

+1

@JoachimPileborg Lo standard '§ 7.2.2' dice 'Gli identificatori in un elenco di enumeratori sono dichiarati come costanti e possono apparire ovunque siano richieste costanti. – lcs

risposta

3

Secondo lo standard, Clang ha ragione nel rifiutare il codice.

t2.m è un'espressione di accesso membro della classe. [Expr.ref]/1 dice:

[...] The postfix expression before the dot or arrow is evaluated; the result of that evaluation, together with the id-expression, determines the result of the entire postfix expression.

C'è anche una nota:

If the class member access expression is evaluated, the subexpression evaluation happens even if the result is unnecessary to determine the value of the entire postfix expression, for example if the id-expression denotes a static member.

Così, la sottoespressione t2 viene valutata. [Expr.const] /2.9 dice che un'espressione e non può essere un'espressione costante core se la valutazione risulta nella valutazione di

an id-expression that refers to a variable or data member of reference type unless the reference has a preceding initialization and either

  • it is initialized with a constant expression or
  • its lifetime began within the evaluation of e ;

t2 si riferisce ad una variabile di tipo di riferimento che non soddisfa i proiettili, così t2.m non è un'espressione costante perché non è un'espressione di costante di nucleo.


Tutte le citazioni da N4594, l'attuale bozza di lavoro pubblicata. Il testo è leggermente cambiato dal C++ 11, ma il significato in questo caso è lo stesso.

+0

Thx. Qualcuno ha segnalato un bug report per gcc? –

+0

@ClaasBontus Non l'ho fatto. Una ricerca attraverso il database dei bug sarebbe in ordine, ma non ho avuto il tempo di farlo fino ad ora. – bogdan

+0

Forse [Bug 39970] (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39970). –

Problemi correlati