I just discovered that a constexpr
method can return correctly the value of a class member that changes during execution. My question is, how is this possible if constexpr
methods are supposed to be evaluated completely at compile time?
The example below correctly outputs Value: 0
and then Value: 5
. Even more, if I change the a.change(5)
to something unpredictible for the compiler (such as a.change(atoi(argv[1]))
or a.change(rand() % 10 + 1)
it still works. Why? Why does it even compile?
#include <iostream>
class A
{
public:
void change(int value) { x = value; }
int get() const { return x; }
constexpr int value() const noexcept { return x; }
private:
int x{0};
};
int main()
{
A a;
std::cout << "Value: " << a.get() << std::endl;
a.change(5);
std::cout << "Value: " << a.get() << std::endl;
}
Thank you in advance
In your example you're not even calling the constexpr
function, you're calling get
, which is not constexpr
.
However, constexpr
functions can be evaluated at compile time, but also during run time if compile time evaluation is not possible.
If you called value
instead of get
, it would still work and the function would be evaluated at run time.
In order to force compile time evaluation, you can write
constexpr auto val = a.value();
This will indeed give you an error if compile time evaluation is not possible.
constexpr
means that you can use that function in a core constant expression, as long as you have constexpr
arguments for it. It can still be used in other contexts.
As it stands, you can't use A::value
in a core constant expression, because you have no way of getting a constexpr A
. If you instead had
class A
{
public:
constexpr A() = default;
constexpr void change(int value) { x = value; }
constexpr int get() const noexcept { return x; }
private:
int x{1};
};
You could write a function that modified an A
at compile time.
constexpr int stuff(A a) {
a.change(10);
return a.get();
}
See it on coliru
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With