我要做的是让一些类继承自extention
类。问题是extention
类必须知道它正在扩展哪个类。
这可以简单地实现:
template<typename Self>
class Extention
{
public:
void check() const
{
std::cout << "Extention is valid: "
<< std::boolalpha
<< std::is_base_of<Extention, Self>::value
<< std::endl;
}
};
class Foo : public Extention<Foo> {};
class Bar : public Extention<void> {};
Foo
和Bar
类显示了扩展的良好和不良用法。
Foo().check(); → Extention is valid: true
Bar().check(); → Extention is valid: false
我想在编译期间检查模板的有效性,这让我写了
template<typename Self>
class Extention
{
static_assert(std::is_base_of<Extention, Self>::value);
};
但是,gcc告诉我这个static_assert
错误,因为class Foo
的类型不完整。
我做错了什么?
修改:我使用-std=c++17
,错误不是static_assert
答案 0 :(得分:2)
我做错了什么?
由于[meta.rel],std::is_base_of
要求派生类型是完整类型:
如果
Base
和Derived
是非联合类类型且不可能是相同类型的cv限定版本,则Derived
应为完整类型。
另一方面,[class.mem/6]表示:
在类说明符的结束
}
,类被视为完全定义的对象类型(或完整类型)。 [...]
那不是你的情况。当您实例化Extension<Foo>
时,Foo
本身远未完全定义。
换句话说,您不能在班级范围内使用static_assert
。将它放在析构函数的主体中(实际上我的首选解决方案,即使它有一些缺点)或任何其他(特殊)成员方法的主体(如果您愿意)。