I've run into what seems a counterintuitive error, namely, the inability to assign the value of a constexpr
function to a constexpr
literal (hope I'm using the language right). Here's the example:
class MyClass {
public:
static constexpr int FooValue(int n) { return n + 5; }
static constexpr int Foo5 = FooValue(5); // compiler error
static constexpr int Foo5Alt(void) { return FooValue(5); } // OK
};
In GCC 4.8.4, Foo5
is flagged for field initializer is not constant
. Found this thread suggesting that the older version of GCC might be the culprit. So I plugged it into Coliru (GCC 6.2.0) and got the error 'static constexpr int MyClass::FooValue(int)' called in a constant expression before its definition is complete
. I added Foo5Alt()
which returns its value as a constexpr
function rather than literal, and that compiles fine.
I guess I'm not following why FooValue(5)
can't be used as the initializer for Foo5
. The definition for FooValue(int n)
is complete, isn't it? { return n + 5; }
is the entire definition. constexpr
denotes an expression that can be fully evaluated at compile time, so why can it not be used to define the return value of a constexpr
literal?
What subtlety of C++ am I missing?
In C++, inline definitions of member functions for a class are only parsed after the declaration of the class is complete.
So even though the compiler "knows" about MyClass::FooValue(int)
, it hasn't "seen" its definition yet, and hence it can't be used in a constexpr
expression.
A general workaround for this is to stick to constexpr
member functions, or declare constexpr
constants outside the class.
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