Both GCC and MSVC seem to allow defining constexpr accessor functions for non-const data members:
#include <random>
#include <iostream>
class Foo
{
int val;
public:
Foo(int v) : val(v) {}
constexpr int get_val() { return val; } // OK
};
int main()
{
std::random_device rd;
Foo foo((int)rd());
std::cout << foo.get_val(); // works
}
Is this nonstandard behavior from MSVC and GCC or does the standard actually allow this?
CodePudding user response:
Of course this is allowed! constexpr
don't mean const
. You can even mutate values in a constexpr
function:
class Foo
{
int val;
public:
constexpr Foo(int v) : val(v) {} // OK
constexpr int get_val() { return val; } // OK
constexpr void set_val(int v) { val = v; } // OK
};
With this you can write constexpr functions that look like normal function, it's just that they may be executed at compile time in the compiler runtime.
constexpr int test() {
Foo f{};
f.set_val(2);
return f.get_val();
}
static_assert(test() == 2); // Checks at compile time