static_assert内部/外部类定义 [英] static_assert inside/outside class definition

查看:64
本文介绍了static_assert内部/外部类定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么static_assert需要不在类定义之外?



失败代码

  #include< type_traits> 

A类
{
public:
A(A&&)noexcept {}
static_assert(std :: is_nothrow_move_constructible< A> ::值, ERROR);
};

int main()
{
}

工作代码

  #include< type_traits> 

类别A
{
public:
A(A&&)noexcept {}

};

static_assert(std :: is_nothrow_move_constructible< A> :: value, ERROR);

int main()
{
}

什么时候在类或结构的定义中使用static_asserts合适?

解决方案

code> static_assert 本身担心代码的两个版本均有效。因此,不, static_assert 不必在类定义之外。正式 static_assert 声明



您遇到的问题与 static_assert 本身无关。 / p>

这里的问题是用作 static_assert std :: is_nothrow_move_constructible )要求类类型为 complete 才能正常工作。但是在类 A 类的定义内,类型 A 尚未完成,这使您的参数表达式无效。这就是为什么 static_assert 仅在类定义(其中 A 完成)之外按预期工作的原因。但是,这完全是关于 std :: is_nothrow_move_constructible 的正确用法,而不是 static_assert 本身。



请注意,即使成员函数在类定义中定义,内部成员函数主体类的类型也完整地视为完整类型。使用此功能,您可以将代码重写为

  A类
{
public:
A(A&)noexcept {
static_assert(std :: is_nothrow_move_constructible< A> :: value, ERROR);
}
};

std :: is_nothrow_move_constructible< A> 会产生正确的结果。


Why does static_assert need to be out side of the class definition?

Failing code

#include <type_traits>

class A
{
public:
    A(A&&) noexcept {}
    static_assert(std::is_nothrow_move_constructible<A>::value, "ERROR");
};

int main()
{
}

Working code

#include <type_traits>

class A
{
public:
    A(A&&) noexcept {}

};

static_assert(std::is_nothrow_move_constructible<A>::value, "ERROR");

int main()
{
}

And when is it appropriate to use static_asserts in the definition of a class or struct?

解决方案

As far as the placement of static_assert itself is concerned both versions of your code are valid. So, no, static_assert does not need to be outside of class definition. Formally static_assert is a declaration. It is allowed wherever declarations are allowed.

The problem you are having has nothing to do with static_assert itself.

The problem here is that the expression that you use as the argument of your static_assert (std::is_nothrow_move_constructible) requires the class type to be complete to work properly. But inside the definition of class A class type A is not complete yet, which makes your argument expression invalid. This is why your static_assert works as intended only outside the class definition, where A is complete. However, this is entirely about proper usage of std::is_nothrow_move_constructible, not about static_assert itself.

Note, that inside member function bodies class type is seen in its entirety, as complete type, even if the member function is defined inside the class definition. Using this feature you can rewrite your code as

class A
{
public:
    A(A&&) noexcept {
      static_assert(std::is_nothrow_move_constructible<A>::value, "ERROR"); 
    }
};

and std::is_nothrow_move_constructible<A> will produce the proper result.

这篇关于static_assert内部/外部类定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆