Рассмотрим следующий код:Компилятор ошибок при использовании CRTP с 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;
Это компилирует штрафа на НКУ, но если я раскомментировать static_assert
линию, она жалуется, что
error: incomplete type 'Derived' used in nested name specifier
static constexpr int x_base = Derived::x_derived;
Я пробовал с разными версии gcc от 4.9 до 5.3, и я получаю ту же ошибку (вы можете попробовать ее на godbolt here). лязг отказывается компилировать его даже без static_assert
, и жалуется, что
error: no member named 'x_derived' in 'Derived'
static constexpr int x_base = Derived::x_derived;
Какой компилятор правильно (если таковые имеются)? Есть ли хороший способ исправить код?
Спасибо за отличный ответ Барри. Итак, если я правильно вас понял, то факт, что gcc принимает код без static_assert, является ошибкой компилятора, а clang является правильным в его отказе? – toth
@toth gcc не отклоняет его, пока вы его не используете в любом месте, поэтому в этом отношении он немного дружелюбен. Но не имеет смысла просто объявлять переменную, которую вы никогда не используете, поэтому она правильно отвергает ее там, где это важно. – Barry
, но gcc позволяет мне использовать его, если он не находится в static_assert. Например, https://godbolt.org/g/rfbH5c (в то время как clang продолжает отклонять код). Итак, один из компиляторов должен быть не прав, любая идея, которая? – toth