2014-09-17 8 views
10

Qualcuno può provare a spiegarlo?Strange comportamento di constexpr per la classe interna

template<typename T, size_t S = T::noElems()> 
struct C 
{ 
}; 

struct X 
{ 
    enum E { A, B, C }; 
    static constexpr size_t noElems() { return C+1; }; 
}; 

struct K 
{ 
    C<X> cx; // this DOES compile 
}; 

struct Y 
{ 
    struct Z 
    { 
     enum E { A, B, C }; 
     static constexpr size_t noElems() { return C+1; }; 
    }; 
    C<Z, Z::C+1> cyz; // this DOES compile 

    C<Z> cyz; // <--- this does NOT compile 
}; 
+0

Clang lamenta la funzione non definita 'noElems' non può essere utilizzata in un'espressione costante' –

+2

Penso che si possa rispondere [qui] (http://stackoverflow.com/a/8108406/4035785) –

+0

Puoi aggiungere la compilation errore nella tua domanda? – Angew

risposta

5

Con la dichiarazione della struct

struct Y 
{ 
    struct Z 
    { 
     enum E { A, B, C }; 
     static constexpr size_t noElems() { return C+1; }; 
    }; 
    C<Z, Z::C+1> cyz1; // this DOES compile 

    C<Z> cyz2; // <--- this does NOT compile 
}; 

entità cyz1 e cyz2 vengono analizzati prima della dichiarazione in linea di Z::noElems(), quindi la definizione di

static constexpr size_t noElems() { return C+1; }; 

non è disponibile al momento della dichiarazione di

C<Z> cyz2; 
+0

+1 Bella risposta. Mi chiedo come sia disponibile Z :: C, quindi. – gd1

+1

Ho modificato la mia risposta, penso che sia NoElems in linea, il che rende il compilatore in grado di analizzarlo dopo le dichiarazioni del cyz, mentre enum E è disponibile, ecco perché cyz1 funziona –

Problemi correlati