[英]Compiler error when using CRTP with static_assert
Consider the following code: 请考虑以下代码:
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;
This compiles fine on gcc but if I uncomment the static_assert
line, it complains that 这在gcc上编译得很好但是如果我取消注释
static_assert
行,它就会抱怨
error: incomplete type 'Derived' used in nested name specifier
static constexpr int x_base = Derived::x_derived;
I tried it with different versions of gcc from 4.9 to 5.3 and I get the same error (you can try it on godbolt here ). 我从4.9到5.3的不同版本的gcc试了一下,我也得到了同样的错误(你可以尝试在godbolt 这里 )。 clang refuses to compile it even without the
static_assert
, and complains that 即使没有
static_assert
,clang也拒绝编译它,并抱怨说
error: no member named 'x_derived' in 'Derived'
static constexpr int x_base = Derived::x_derived;
Which compiler is correct (if any)? 哪个编译器是正确的(如果有的话)? Is there a nice way to fix the code?
有没有一种很好的方法来修复代码?
Accessing nested names requires the class to be complete, but Derived
isn't complete here yet: 访问嵌套名称需要完成类,但
Derived
尚未完成:
template<typename Derived>
struct Base {
static constexpr int x_base = Derived::x_derived;
^^^^^^^^^
};
so the code is ill-formed. 所以代码是不正确的。
There are a few workarounds. 有一些解决方法。 First, you can separately just pass in the value as a template argument:
首先,您可以单独传递值作为模板参数:
template <typename Derived, int x_derived>
struct Base {
static constexpr int x_base = x_derived;
};
struct Derived : public Base<Derived, 5> { };
Second, if possible (eg you don't need x_derived
to declare any members), you can move the value into a function to delay its instantiation: 其次,如果可能(例如,您不需要
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.