Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to cast enums?

I have a third-party unscoped enum (that I can't modify) that I'd really like to cast to my own scoped enum. How can I provide something like a conversion operator?

What I'd like to do is something like this:

#include <iostream>
enum ThirdPartyLetter {
  A=4,
  B=5
};

enum class MyNumber {
  ONE=1,
  TWO=2

  // This doesn't compile, of course
  /*Number(const ThirdPartyLetter& rhs) {
    if(rhs == ThirdPartyLetter::A) {
      return ONE;
    }
    else {
      return TWO;
    }
  }*/
};


int main() {
  ThirdPartyLetter letter = ThirdPartyLetter::A;
  MyNumber number = static_cast<MyNumber>(letter);
  // Without the cast, this prints 4 (an invalid enum value!)
  std::cout << int(number) << std::endl;
}

Is there a way to provide some kind of casting from ThirdPartyNumber to MyNumber?

like image 824
Thomas Johnson Avatar asked Jan 07 '17 22:01

Thomas Johnson


1 Answers

An idiomatic way to do that at compile-time in C++ is using traits.
As an example:

enum Foo { ONE, TWO };
enum Bar { THREE, FOUR };

template<Foo> struct conv;
template<> struct conv<Foo::ONE> { static constexpr Bar value = Bar::THREE; };
template<> struct conv<Foo::TWO> { static constexpr Bar value = Bar::FOUR; };

If you want to do that at runtime, maybe a switch is well suited.
Anyway, you can still use traits to centralize your conversion logic and do something like this:

Bar get(Foo choice) {
    switch(choice) {
    case Foo::ONE:
        return conv<ONE>::value;
     case Foo::TWO:
        return conv<TWO>::value;
    }
}
like image 75
skypjack Avatar answered Oct 02 '22 14:10

skypjack