[英]Compiler error when using CRTP with 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;
這在gcc上編譯得很好但是如果我取消注釋static_assert
行,它就會抱怨
error: incomplete type 'Derived' used in nested name specifier
static constexpr int x_base = Derived::x_derived;
我從4.9到5.3的不同版本的gcc試了一下,我也得到了同樣的錯誤(你可以嘗試在godbolt 這里 )。 即使沒有static_assert
,clang也拒絕編譯它,並抱怨說
error: no member named 'x_derived' in 'Derived'
static constexpr int x_base = Derived::x_derived;
哪個編譯器是正確的(如果有的話)? 有沒有一種很好的方法來修復代碼?
訪問嵌套名稱需要完成類,但Derived
尚未完成:
template<typename Derived>
struct Base {
static constexpr int x_base = Derived::x_derived;
^^^^^^^^^
};
所以代碼是不正確的。
有一些解決方法。 首先,您可以單獨傳遞值作為模板參數:
template <typename Derived, int x_derived>
struct Base {
static constexpr int x_base = x_derived;
};
struct Derived : public Base<Derived, 5> { };
其次,如果可能(例如,您不需要x_derived
來聲明任何成員),您可以將值移動到函數中以延遲其實例化:
template<typename Derived>
struct Base {
static constexpr int x_base() {
static_assert(Derived::x_derived > 1, "Oops");
return Derived::x_derived;
}
};
struct Derived : public Base<Derived> {
static constexpr int x_derived = 5;
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.