Question

I would like some way to evaluate a switch-class statement using class members that are not integer or eum.

The real question is how to make those class members const-expression i.e. those members must be known as constant at compile-time.

I tried the code below with static const, but it works only when in the case statements there are integers.

I was looking at new C++11 constexpr that would do the job.

What If I have not available that keyword? Is there anyway or trick or anything to allow my class members (non integer or enum) being const expressions?

I am using Linux and g++. Also any g++ specific keyword would be appreciated.

  class MyEnum
  {
  public:
    int val_;
    MyEnum(){}
    MyEnum(int v): val_(v){}
    operator int(){return val_;}
    static const MyEnum ALFA;
    static const MyEnum BETA;
    void foo() {
       // do something.
    }
  };

  const MyEnum MyEnum::ALFA(1);
  const MyEnum MyEnum::BETA(2);

  void testEnum()
  {
    MyEnum val = MyEnum::ALFA;

    switch(val)
    {
      case 0: //works
      //case MyEnum::ALFA:// doesn't work
      cout << "ciao" << endl;
      break;
      case 1: //works
      //case MyEnum::BETA: // doesn't work
      cout << "bello" << endl;
      break;
      default:
      break;
    } 
  }
Was it helpful?

Solution

This seems to do what you want:

#include <iostream>

enum class MyEnum { ALFA, BETA };

int main() {
    MyEnum a = MyEnum::BETA;

    switch( a ) {
        case MyEnum::ALFA:
            std::cout << "ALFA\n";
            break;
        case MyEnum::BETA:
            std::cout << "BETA\n";
            break;
    }
}

EDIT:

As per Edward's comment, below, here goes an example of how you can have this without enum (in my case, enum class -- that creates a new type) or int:

#include <iostream>

class MyEnum {
    struct Alfa { constexpr operator int() const { return 0; } };
    struct Beta { constexpr operator int() const { return 1; } };
    int v;
public:
    constexpr static Alfa ALFA {};
    constexpr static Beta BETA {};
    MyEnum(const MyEnum&) = default;
    constexpr MyEnum(Alfa vv): v(vv) {}
    constexpr MyEnum(Beta vv): v(vv) {}
    constexpr MyEnum() : MyEnum(ALFA) {}
    operator int () const { return v; }
};

int main() {
    MyEnum a = MyEnum::BETA;
    a = MyEnum::ALFA;

    switch( a ) {
        case MyEnum::ALFA:
            std::cout << "ALFA\n";
            break;
        case MyEnum::BETA:
            std::cout << "BETA\n";
            break;
    }
}

That is far more complicated (live here) :D

OTHER TIPS

Here's a way to do something like what I think you're asking. I've modified your MyEnum class so that it is `constexpr and the variable val so that it's int. ALFA and BETA are instances of MyEnum rather than both instances and members as in your original code. Just to make things interesting, the cast operator does more than simply passing back the internal data.

#include <iostream>
using namespace std;

class MyEnum
{
public:
    constexpr MyEnum(int n) : data(n) {}
    constexpr operator int(){return data+5;}
private:
    int data;
};

static constexpr MyEnum ALFA{0};
static constexpr MyEnum BETA{1};

void testEnum()
{
    int val = 5;

    switch(val)
    {
    case int(ALFA):
        cout << "ciao" << endl;
        break;
    case int(BETA):
        cout << "bello" << endl;
        break;
    default:
        break;
    } 
}

int main()
{
    testEnum();
}

This prints ciao as expected.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top