Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using constexp member function in switch

Why I can use constexp non-member function in switch, but when I use member function compiler is saying: "the value of ‘y’ is not usable in a constant expression"?

class Test {
public:
    constexpr Test(int i) : i(i) { }
    constexpr int get() {return i;};
private:
    int i;
};

constexpr int test()
{
    return 1;
}

int main() {
    int x = 0;

    Test y = Test(4);

    switch (x) {
    case test(): // this is OK
            break;
    case y.get(): // not working
        break;
    }
}
like image 680
Yanny Avatar asked Feb 24 '26 13:02

Yanny


2 Answers

Declare y as a constant expression:

constexpr Test y = Test(4);

Demo

Reason:

Although, Test::get() is declared constexpr object y is not.

like image 150
101010 Avatar answered Feb 26 '26 01:02

101010


Introduction

The problem with your code is that the Standard (n3337) mandates that each expression associated with a label must be a constant-expression.

6.4.2p2 The switch statement [stmt.switch]

Any statement within the switch statement can be labeled with one or more case labels as follows:

case constant-expression :

where the constant-expression shall be a converted constant expression (5.19) of the promoted type of the switch condition.

Since y is not declared in a constant-expression friendly matter, y.get() isn't usable when specifying the needle for a certain case-label. The member-function is constexpr, but the instance of Test isn't, which renders the usage of Test::get as a non-constant expression.


Solution

To solve this issue you will need to declare y with the constexpr specifier to enable its usage in the context you are looking for, and I'm guessing you already know how:

constexpr Test y (4);
like image 21
Filip Roséen - refp Avatar answered Feb 26 '26 03:02

Filip Roséen - refp