Abruzzo Forte e Gentile
Abruzzo Forte e Gentile

Reputation: 14869

Switch case statement with member variable in case

I am trying to find a way to evaluate a switch-case statement using a member variable in the case part. I thought that having a global static variable like below would be allowed as const-expression.

Unfortunately the compiler tells me the opposite:

error: ‘ll’ cannot appear in a constant-expression
error: ‘.’ cannot appear in a constant-expression

Is there any keyword or anything that would allow this idea to work? I am not an expert of C++11, and I heard about constexpr.

enum MyEnum2 {A=0, B=1};

class Test{
    public:
        operator MyEnum2 () { return val_;}
        Test(MyEnum2 val) :val_(val) {}
        Test() {}
        static const MyEnum2 A;
        static const MyEnum2 B;
        MyEnum2 val_;
};

const MyEnum2 Test::A(MyEnum2::A);
const MyEnum2 Test::B(MyEnum2::B);

static const Test ll;

int main() {
    class Test v = ll.A;
    cout << v << endl;
    switch(v) {
        case ll.A:
            cout << "A" << endl;
            break;

        case ll.B:
            cout << "B" << endl;
            break;
    }
}

Upvotes: 2

Views: 2208

Answers (3)

Jens Munk
Jens Munk

Reputation: 4725

Simply enclose your enumeration in the class. You will get the same syntax and enums are definitions, hence const by default.

#include <iostream>
using namespace std;

class Test {
    public:
        enum MyEnum2 {
            A,
            B
        };

        Test(Test::MyEnum2 type) {
            this->type = type;
        }

        MyEnum2 type;
};

int main() {
    Test t = Test(Test::A);

    switch (t.type) {

        case (Test::A):
            cout << "A" << endl;
            break;

        case (Test::B):
            cout << "B" << endl;
            break;
    }
}

Upvotes: 1

Dr. Debasish Jana
Dr. Debasish Jana

Reputation: 7128

Add a cast operator in Test class as operator int() so that Test object gets type casted to an int

Upvotes: 0

Klaus
Klaus

Reputation: 25633

Static elements are parts of the class and not of the instance. So you have to write:

case Test::A:

Because the value in a case expression must be a constant expression, you can also use a constexpr method like this:

class A
{
    public:
        constexpr int X() { return 42; }
};



int main()
{
    int i=42;
    A a;

    switch (i)
    {
        case a.X():
            ;

    }
}

Edit to answer questions:

You can make a constexpr object of a class which can be instantiated as constexpr which simply needs a constexpr constructor like the following:

#include <iostream>

using namespace std;

const int i = 9;    // using a const variable as compile time const 

class Y             // using a class containing const vals
{
    public:
    int i;
    constexpr Y(int _i): i(_i){}
};

constexpr Y y(100);

int main()
{
    int var=9;

    switch (var)
    {
        case i:
            ;

        case y.i:
            ;
    }
}

But I can see not any real use case for this kind of programming. The switch statement can not be "reused" with an other instance, because you can not give a switch expression a other "object" of constants to behave different. So you simple hide your constant values in a very special way which is maybe not so nice for others to read.

Can you give us your use case please?

Upvotes: 4

Related Questions