如何静态断言枚举元素的值?

时间:2013-10-16 15:48:49

标签: c++

例如:

enum class MyEnum { A, B };
static_assert(A == 0 && B == 1); // error: expected constructor, destructor, or type conversion before '(' token

我如何实现这一目标?

5 个答案:

答案 0 :(得分:8)

enum class添加到语言的主要目的是使枚举强类型作用域。这意味着:

  • 您无法在没有资格的情况下使用A。您必须使用MyEnum::A

  • 您不能将其视为int - 强类型枚举无法与不使用显式强制转换的整数类型进行比较。

所以你必须做这样的事情:

static_assert(to_integral(MyEnum::A)== 0 && to_integral(MyEnum::B)==1, 
                              "your message");

this answer开始实现to_integral:它是一个通用实现,因此您不必假设或弄清楚MyEnum的基础类型是什么。< / p>

或者,您可以为operator==定义MyEnum。确保它是constexpr

constexpr bool operator==(MyEnum x, int y) { return to_integral(x) == y; }
constexpr bool operator==(int x, MyEnum y) { return y == x; }

现在你可以这样写:

static_assert(MyEnum::A== 0 && MyEnum::B ==1, "your message");

为了完整起见,我从my other answer复制粘贴to_integral的实施:

#include <type_traits> //must include it

template<typename E>
constexpr auto to_integral(E e) -> typename std::underlying_type<E>::type 
{
   return static_cast<typename std::underlying_type<E>::type>(e);
}

希望有所帮助。

答案 1 :(得分:2)

您的代码有两个问题:

  1. static_assert有两个参数
  2. 您无法比较A0,因为:
    1. MyEnum不仅仅是enum,还有class enum。所以,首先,你必须写MyEnum::A
    2. 您无法将MyEnum::A0进行比较,因为MyEnum是强类型的枚举。在比较之前,您必须将其强制转换为int
  3. 但是如果您使用强类型枚举,我猜,您不需要将它与int进行比较。

答案 2 :(得分:2)

尝试通过枚举访问,并转换枚举值:

enum class MyEnum { A, B };
static_assert((int)MyEnum::A == 0 && (int)MyEnum::B == 1, "message");

答案 3 :(得分:2)

你有四个问题。你需要

enum class MyEnum { A, B };
static_assert(MyEnum::A == MyEnum(0) && MyEnum::B == MyEnum(1), "invalid values");

修正了

  • 枚举值的范围(AMyEnum::A
  • 将整数值正确转换为枚举,以便比较有效
  • static_assert
  • 添加了遗漏的错误消息

第四个问题是什么?

您需要在C ++ 11模式下编译(这是其他人遗漏的内容!)。将-std=c++11添加到编译器的命令行。我怎么知道?由于您收到的错误消息,这只在以C ++ 03模式编译时发生。

答案 4 :(得分:1)

static_assert有两个参数,第二个是断言失败时要输出的字符串。

应该是这样的,

static_assert(A == 0 && B == 1, "Enum values are not as expected");