3

For example:

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

How do I achieve this?

quant
  • 21,507
  • 32
  • 115
  • 211

5 Answers5

8

The whole purpose of adding enum class to the language was to make enumeration strongly typed and scoped. This means:

  • You cannot use just A without qualification.You have to use MyEnum::A.

  • You cannot treat it like int — strongly-typed enum cannot be compared with integral type without explicit cast.

So you have to do something like this:

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

And take the implementation of to_integral from this answer : it is a generic implementation, so you don't have to assume or figure out what the underlying type of MyEnum is.

Alternatively, you can define operator== for MyEnum. Make sure it is constexpr:

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

Now you can write this:

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

Just for the sake of completeness, I copy-paste the implementation of to_integral from my other answer:

#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);
}

Hope that helps.

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
2

Your code have two problems:

  1. static_assert takes two arguments
  2. You can't compare A and 0, because:
    1. MyEnum is not just enum, but class enum. So, firstly, you have to write MyEnum::A
    2. You can't compare MyEnum::A with 0, because MyEnum is a strongly-typed enum. You have to cast it to int before comparing.

But if you are using strongly typed enumerations, I guess, you don't need to compare it with ints.

awesoon
  • 32,469
  • 11
  • 74
  • 99
2

Try to access through the enum, and cast the enum values:

enum class MyEnum { A, B };
static_assert((int)MyEnum::A == 0 && (int)MyEnum::B == 1, "message");
Stefan
  • 17,448
  • 11
  • 60
  • 79
2

You have four problems. You need

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

which fixes

  • the scope of the enum values (A vs. MyEnum::A)
  • converts the integer values to enums correctly so the comparison is valid
  • adds the missing error message for static_assert

What's the fourth problem?

You need to compile in C++11 mode (this is what the others are missing!). Add -std=c++11 to the compiler's command line. How do I know? Because of the error message you got, this only happens when compiling in C++03 mode.

Daniel Frey
  • 55,810
  • 13
  • 122
  • 180
1

static_assert takes two arguments, the second being a string to output if the assertion fails.

Should be something like,

static_assert(A == 0 && B == 1, "Enum values are not as expected");
PherricOxide
  • 15,493
  • 3
  • 28
  • 41