Betrachten Sie den folgenden Code ein:Compilerfehler, wenn CRTP Verwendung mit 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;
Dies kompiliert auf gcc in Ordnung, aber wenn ich die static_assert
Linie Kommentar-, wirft sie
error: incomplete type 'Derived' used in nested name specifier
static constexpr int x_base = Derived::x_derived;
Ich versuchte es mit verschiedenen Versionen von gcc von 4.9 bis 5.3 und ich bekomme den gleichen Fehler (Sie können es auf godbolt here versuchen). Klirren weigert sich, es auch ohne die static_assert
zu kompilieren, und beschwert sich, dass
error: no member named 'x_derived' in 'Derived'
static constexpr int x_base = Derived::x_derived;
Which Compiler korrekt ist (falls vorhanden)? Gibt es eine gute Möglichkeit, den Code zu reparieren?
Danke für die gute Antwort Barry. Also, wenn ich Sie richtig verstanden habe, ist die Tatsache, dass gcc den Code ohne static_assert akzeptiert, ein Compiler-Bug, und clang ist korrekt, wenn er diesen zurückweist? – toth
@toth gcc lehnt es nicht ab, bis du es irgendwo benutzt hast - in dieser Hinsicht ist es nur ein bisschen freundlicher. Aber es ist nicht wirklich sinnvoll, nur eine Variable zu deklarieren, die Sie nie benutzen - also lehnt sie sie dort ab, wo sie wichtig ist. – Barry
aber gcc lässt mich es verwenden, solange es nicht in einer static_assert ist. Zum Beispiel https://godbolt.org/g/rfbH5c (während clang den Code weiterhin ablehnt). Also muss einer der Compiler falsch liegen, irgendeine Idee welche? – toth