【问题标题】:static_assert inside/outside class definitionstatic_assert 内部/外部类定义
【发布时间】:2014-11-12 06:59:07
【问题描述】:

为什么 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_asserts?

【问题讨论】:

  • 第一个有什么问题?有错误信息吗?
  • 我已编辑问题标题以匹配问题内容。
  • @0x499602D2 使用 g++ --std=c++11 {code} is_nothrow_move_constructible.cpp:8:1: error: static assertion failed: ERROR static_assert(std: :is_nothrow_move_constructible::value, "ERROR"); {代码}

标签: c++ c++11 typetraits static-assert


【解决方案1】:

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&lt;A&gt; 会产生正确的结果。

【讨论】:

  • 而且,AFAIK,static_assert 可以在函数体内使用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多