为什么static_assert需要在类定义之外?
代码失败
#include <type_traits>
class A
{
public:
A(A&&) noexcept {}
static_assert(std::is_nothrow_move_constructible<A>::value, "ERROR");
};
int main()
{
}
工作代码
#include <type_traits>
class A
{
public:
A(A&&) noexcept {}
};
static_assert(std::is_nothrow_move_constructible<A>::value, "ERROR");
int main()
{
}
什么时候在类或结构的定义中使用static_assert是否合适?
答案 0 :(得分:21)
就static_assert
本身的位置而言,两个版本的代码都是有效的。所以,不,static_assert
不需要在类定义之外。正式static_assert
是声明。只要允许声明,就允许这样做。
您遇到的问题与static_assert
本身无关。
此处的问题是,您用作static_assert
(std::is_nothrow_move_constructible
)参数的表达式要求类类型完成才能正常工作。但是在类A
的定义中,类类型A
尚未完成,这使得您的参数表达式无效。这就是为什么您的static_assert
仅在类定义之外工作,其中A
已完成。但是,这完全是关于std::is_nothrow_move_constructible
的正确使用,而不是关于static_assert
本身。
注意,即使在类定义中定义了成员函数,内部成员函数体类的类型也可以完整地看作完整类型。使用此功能,您可以将代码重写为
class A
{
public:
A(A&&) noexcept {
static_assert(std::is_nothrow_move_constructible<A>::value, "ERROR");
}
};
和std::is_nothrow_move_constructible<A>
将产生正确的结果。