I have the following code:
struct Foo
{
struct Bar
{
std::uint32_t x = -1;
constexpr Bar(std::uint32_t x) : x(x) {}
};
static constexpr Bar CONST_BAR = Bar(0);
};
When I try to compile it I get the following error:
error: ‘constexpr Foo::Bar::Bar(uint32_t)’ called in a constant expression before its definition is complete
Can someone explain to me what is going on? As far as I can see Bar's constructor is defined before the first call.
Live example
It may contain local variable declarations, but the variable must be initialized. It must be a literal type, and can't be static or thread-local. The locally declared variable isn't required to be const , and may mutate. A constexpr non- static member function isn't required to be implicitly const .
const can only be used with non-static member functions whereas constexpr can be used with member and non-member functions, even with constructors but with condition that argument and return type must be of literal types.
A static constexpr variable has to be set at compilation, because its lifetime is the the whole program. Without the static keyword, the compiler isn't bound to set the value at compilation, and could decide to set it later.
The constexpr specifier declares that it is possible to evaluate the value of the function or variable at compile time. Such variables and functions can then be used where only compile time constant expressions are allowed (provided that appropriate function arguments are given).
I don't have a detailed explanation but I happened to have stumbled upon this problem as well and thought it was at least worth mentioning... Other than placing the definition of CONST_BAR
outside of struct Foo
, another possible workaround is instantiating Foo
:
// Example program
#include <iostream>
#include <string>
template<typename T = void>
struct Foo
{
struct Bar
{
std::uint32_t x = -1;
constexpr Bar(std::uint32_t x) : x(x) {}
};
static constexpr Bar CONST_BAR = Bar(0);
};
int main()
{
std::cout << "x: " << Foo<>::CONST_BAR.x << "\n";
}
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