6
考虑下面的代码:编译器错误使用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
@tcc gcc不会拒绝它,除非你真的在任何地方使用它 - 所以它只是在这方面有点友善。但是声明一个你永远不会使用的变量并不是真正有意义的 - 所以它正确地拒绝它在重要的地方。 – Barry
但gcc确实让我使用它,只要它不在static_assert中。例如https://godbolt.org/g/rfbH5c(同时clang继续拒绝该代码)。所以其中一个编译器一定是错的,有什么想法呢? – toth