Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When non-const members can be used in constexpr member functions?

I encountered a situation I don't understand. Would somebody be so nice to explain why first code compiles correctly while second gives an error:

error: the value of 'TestClass::z' is not usable in a constant expression
static constexpr int sum() {return x+y+z;}
----------------------------------------------------^
note: 'int TestClass::z' is not const static int z;"

Working code:

#include <iostream>

using namespace std;

class TestClass
{
    public:
        constexpr int sum() {return x+y+z;}

    private:
        static constexpr int x = 2;
        static const int y = 3;
        int z = 5;

};

int main()
{
    TestClass tc;
    cout << tc.sum() << endl;

    return 0;
}

But when I try to make TestClass::sum() static I get aforementioned error:

#include <iostream>

using namespace std;

class TestClass
{
    public:
        static constexpr int sum() {return x+y+z;}

    private:
        static constexpr int x = 2;
        static const int y = 3;
        static int z;

};

int TestClass::z = 5;

int main()
{
    TestClass tc;
    cout << tc.sum() << endl;

    return 0;
}

P.S. I'm using mingw32-g++ 4.8.1

like image 865
Lehu Avatar asked Oct 19 '22 15:10

Lehu


1 Answers

In the first case, the result depends only on the function's arguments, including the implicit this used to access z. This doesn't disqualify it from being constexpr - if all the arguments are constant expressions, then so is the result.

In your example, it isn't a constant expression (since tc isn't), but that doesn't matter since it's not being used in a context that requires one. Here's an example showing its use in a constant expression:

constexpr TestClass tc;
array<int, tc.sum()> a;
cout << a.size() << endl;

In the second case, the result also depends on a static variable, whose value could change during the program. This does disqualify it - even if all the arguments are constant expressions, z isn't, and so the result of a function call can never be a constant expression.

like image 109
Mike Seymour Avatar answered Oct 28 '22 20:10

Mike Seymour