Question

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;
    }
}
Was it helpful?

Solution

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?

OTHER TIPS

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

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

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