Reputation: 1807
struct test {
int var;
consteval test(int i) : var{i}
{
static_assert(i == 3);
}
};
int main()
{
constexpr test t{3};
}
This is rejected with:
$ g++ c.cpp -std=c++20
c.cpp: In constructor ‘consteval test::test(int)’:
c.cpp:8:25: error: non-constant condition for static assertion
8 | static_assert(i == 3);
| ~~^~~~
c.cpp:8:23: error: ‘i’ is not a constant expression
8 | static_assert(i == 3);
| ^
Why can't I use static_assert
if the constructor is guaranteed to be evaluated at compile time ?
Upvotes: 1
Views: 133
Reputation: 61
Function parameters are not usable as constant expressions. If you want to do compile-time checking you can try to do some workarounds though.
Take this code for example:
consteval void static_assert_num(auto number_to_check, int asserted_value)
{
number_to_check /= (number_to_check == asserted_value);
}
struct test {
int var;
consteval test(int i) : var{i}
{
static_assert_num(i, 3);
}
};
int main()
{
constexpr test t{3}; // no error
constexpr test t{4}; // compilation error
}
Not the cleanest code, and maybe someone can come up with something better, but this seems to do the job. We can abuse the fact that constexpr doesn't allow for UB, so we just divide by zero to force an error (more examples found in this thread).
Upvotes: 3
Reputation: 76889
It doesn't work that way.
When you write static_assert(i == 3);
in the function definition, then you are asking the compiler to check that condition to be true while compiling the definition of the function. At that point i
is not known.
Formally, i == 3
must itself be a constant expression, but i
is not usable in constant expressions because it is not a compile-time constant (function parameters never are).
Upvotes: 5