由于类型不完整,在 static_assert 中使用 std::is_base_of 失败
using std::is_base_of in static_assert fails due to incomplete type
我想做的是让一些 classes 继承自 extention
class。问题是 extention
class 必须知道它正在扩展哪个 class。
这可以像这样简单地实现:
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
class 显示扩展的好坏用法。
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
中缺少错误消息
What am I doing wrong ?
因为[meta.rel],std::is_base_of
要求派生类型是完整类型:
If Base
and Derived
are non-union class types and are not possibly cv-qualified versions of the same type, Derived
shall be a complete type.
另一方面,[class.mem/6] 指出:
A class is considered a completely-defined object type (or complete type) at the closing }
of the class-specifier. [...]
那不是你的情况。当您实例化 Extension<Foo>
时,Foo
本身远未完全定义。
换句话说,您不能在 class 范围内使用 static_assert
。将它放在析构函数的主体中(实际上我的首选解决方案,即使它有一些缺点)或任何其他(特殊)成员方法的主体,如果你愿意的话。
我想做的是让一些 classes 继承自 extention
class。问题是 extention
class 必须知道它正在扩展哪个 class。
这可以像这样简单地实现:
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
class 显示扩展的好坏用法。
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
What am I doing wrong ?
因为[meta.rel],std::is_base_of
要求派生类型是完整类型:
If
Base
andDerived
are non-union class types and are not possibly cv-qualified versions of the same type,Derived
shall be a complete type.
另一方面,[class.mem/6] 指出:
A class is considered a completely-defined object type (or complete type) at the closing
}
of the class-specifier. [...]
那不是你的情况。当您实例化 Extension<Foo>
时,Foo
本身远未完全定义。
换句话说,您不能在 class 范围内使用 static_assert
。将它放在析构函数的主体中(实际上我的首选解决方案,即使它有一些缺点)或任何其他(特殊)成员方法的主体,如果你愿意的话。