【问题标题】:How do I statically assert the value of enum elements?如何静态断言枚举元素的值?
【发布时间】:2015-05-11 06:41:34
【问题描述】:

例如:

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

我如何实现这一目标?

【问题讨论】:

  • 您还缺少字符串文字部分。
  • @chris 谢谢,已修复。

标签: c++


【解决方案1】:

在语言中添加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 的底层类型是什么。

或者,您可以为MyEnum 定义operator==。确保它是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);
}

希望对您有所帮助。

【讨论】:

    【解决方案2】:

    你的代码有两个问题:

    1. static_assert 接受两个参数
    2. 你不能比较A0,因为:
      1. MyEnum 不仅仅是enum,而是class enum。所以,首先,你必须写MyEnum::A
      2. 您不能将MyEnum::A0 进行比较,因为MyEnum 是一个强类型枚举。在比较之前,您必须将其转换为 int

    但如果你使用的是强类型枚举,我猜,你不需要和ints比较。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

        你有四个问题。你需要

        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 模式编译时发生。

        【讨论】:

          【解决方案5】:

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

          应该是这样的,

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-06-01
            • 1970-01-01
            • 1970-01-01
            • 2020-03-30
            • 1970-01-01
            相关资源
            最近更新 更多