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