2016-03-07 12 views
8

considerare il mio semplice esempio qui sotto:Curiosamente ricorrente modello di modello (CRTP) con constexpr statico Clang

#include <iostream> 

template <typename T> 
class Base 
{ 
public: 
    static constexpr int y = T::x; 
}; 

class Derived : public Base<Derived> 
{ 
public: 
    static constexpr int x = 5; 
}; 


int main() 
{ 
    std::cout << Derived::y << std::endl; 
} 

In g ++, questo compila bene e stampe 5 come previsto. In Clang, tuttavia, non riesce a compilare con l'errore no member named 'x' in 'Derived'. Per quanto posso dire questo è il codice corretto. C'è qualcosa di sbagliato in quello che sto facendo, e se no, c'è un modo per avere questo lavoro in Clang?

+0

domanda molto simile: http://stackoverflow.com/q/35759047/996886 – melak47

+0

Se si inizializza 'y' al di fuori del' base' la classe funziona? –

+0

@Ben non è possibile inizializzare un 'constexpr static int' al di fuori della classe. – melak47

risposta

0

Questo probabilmente non è la risposta a nessuno sarebbe in cerca di, ma ho risolto il problema con l'aggiunta di una terza classe:

#include <iostream> 

template <typename T> 
class Base 
{ 
public: 
    static constexpr int y = T::x; 
}; 

class Data 
{ 
public: 
    static constexpr int x = 5; 
}; 

class Derived : public Base<Data>, public Data {}; 

int main() 
{ 
    std::cout << Derived::y << std::endl; 
} 

Funziona, se lo desideri, ma purtroppo in realtà non hanno i vantaggi di CRTP!

1

Come collegato nei commenti, Initializing a static constexpr data member of the base class by using a static constexpr data member of the derived class suggerisce che il comportamento clang è conforme standard fino a C++ 14 qui. A partire da Clang 3.9, il codice viene compilato correttamente con -std=c++1z. Un facile soluzione possibile è quella di utilizzare le funzioni constexpr invece di valori:

#include <iostream> 

template <typename T> 
class Base 
{ 
public: 
    static constexpr int y() {return T::x();} 
}; 

class Derived : public Base<Derived> 
{ 
public: 
    static constexpr int x() {return 5;} 
}; 

int main() 
{ 
    std::cout << Derived::y() << std::endl; 
}