Si consideri il seguente codice:Compiler errore quando utilizza CRTP con static_assert
template<typename Derived>
struct Base {
static constexpr int x_base = Derived::x_derived;
//static_assert(x_base > 1, "Oops");
};
struct Derived : public Base<Derived> {
static constexpr int x_derived = 5 ;
};
Base<Derived> obj;
Questo compila bene su gcc ma se togliere il commento alla linea di static_assert
, si lamenta che
error: incomplete type 'Derived' used in nested name specifier
static constexpr int x_base = Derived::x_derived;
ho provato con diversi versioni di gcc da 4.9 a 5.3 e ottengo lo stesso errore (puoi provarlo su Godbolt here). clang si rifiuta di compilarlo anche senza la static_assert
, e si lamenta che
error: no member named 'x_derived' in 'Derived'
static constexpr int x_base = Derived::x_derived;
quale compilatore è corretto (se del caso)? C'è un bel modo per correggere il codice?
Grazie per l'ottima risposta Barry. Quindi, se ho capito bene, il fatto che gcc accetti il codice senza static_assert è un bug del compilatore, e clang è corretto nel respingerlo? – toth
@toth gcc non lo rifiuta finché non lo utilizzi in qualsiasi luogo, quindi è solo un po 'più amichevole a tale riguardo. Ma non è davvero significativo dichiarare semplicemente una variabile che non usi mai, quindi la rifiuta correttamente dove è importante. – Barry
ma gcc mi consente di usarlo, purché non sia in static_assert. Ad esempio, https://godbolt.org/g/rfbH5c (mentre clang continua a rifiutare il codice). Quindi uno dei compilatori deve essere sbagliato, qualche idea che? – toth