Will consteval allow to use static_assert on function arguments?
No. Function arguments have never been, and will continue to not be, usable as constant expressions.
There is a difference between something being constant evaluated and being usable as a constant-expression. consteval
ensures that we’re in a constant evaluation context, but it does not also cause everything to become constant-expressions.
In order to allow function arguments to be usable as constant expressions, you would need to make everything implicitly a template:
template <int> struct X { };
consteval auto foo(int i) {
static_assert(i > 10); // in order to allow this...
return X<i>{}; // ... you'd have to allow this too
}
And now foo(20)
and foo(30)
return different types. That’s a template.
Important background reading for understanding why this is a fundamental and inherent limitation can be found in Andrew Sutton’s Translation and evaluation: A mental model for compile-time metaprogramming:
Having a mental model of compile-time evaluation that physically separates it from the process of
translation has been extremely helpful for me. In particular, it has helped me understand what is not
possible (e.g., instantiating a template during evaluation). This helps prune the design space for
otherwise large and complex language features. Hopefully, others will find this note helpful as well.
With static_assert
specifically though, you can add a workaround just to cause a compilation failure. That’s just adding anything at all that can’t be used during constant evaluation. Like:
#define CONSTEVAL_STATIC_ASSERT(c, msg) do { if (!(c)) throw msg; } while(false)
as in:
consteval char operator""_bchar(const char text[], const size_t length)
{
CONSTEVAL_STATIC_ASSERT(length == 8, "Binary char has to have 8 digits!");
// ...
}