Hello, and welcome to C++ Weekly. I'm your host, Jason Turner. In this episode I want
to cover all of the different ways that I know of of forcing work to be done at compile time,
and we're going to reference the work from another author as well in this.
This episode of C++ Weekly is sponsored by me.
Be sure to check out the video description for important links about upcoming events,
sponsoring the channel with Patreon, buying copies of my Best Practices and Puzzler books,
and how to contact me if you are interested in on-site training or remote code reviews.
Okay. So if you've been following along for the last few episodes you are hopefully aware
that simply making a function or a value 'constexpr' is not sufficient to actually
force the compiler to do that work at compile time.
There's no rule in the standard that says that 'value' has to be calculated at compile time.
Now if we do make it 'static' then that forces the compiler to evaluate it at compile time, which is
helpful, but now it has to be 'const'. Maybe we don't want this to be 'const', we just want it to
be a value that is initialized at compile time. So the next thing that the standard has given us is
this 'constinit'. Now I'm getting a compile time error here because 'constinit' has to be 'static'
so it's not a constant, but it is a 'static'. (These things both fall under that constant
initialization rule that we covered like two episodes ago, so make sure you watch that one
when we're discussing the things about constexpr that you probably have as a misconception.)
So the first one has to be 'const', the second one has to be 'static'.
If we do (let's make sure that we cover all of our bases here)...
So in the first case it's not guaranteed, and it has to be 'const',
and the second case it has to be 'const' and it has to be 'static',
and in the third case here it's not 'const' but it also still has to be 'static'.
So the next option is if we actually change this function to be 'consteval'. Now all of
these things are required to be calculated at compile time, but (let's do this)
'consteval' functions must be passed a compile time constant.
That makes sense because we want this to be done at compile time,
but it doesn't make sense for all functions to be 'consteval' - 'constexpr' is more versatile.
So the next interesting way to force the compiler to give us a compile time
value is one that I referenced indirectly in my previous video.
So if I make this function called 'make_compile_time' and I have a parameter in my
template here and return this back, then I have forced the compiler to evaluate this at compile
time because it must evaluate it at compile time to be a template parameter. Now this brings us
to another option that I was made aware of from Andreas Fertig's blog,
and Andreas runs through several of these options as well and has this function
referred to as 'as_constant'. It's a 'consteval' function that takes an 'auto' parameter.
Andreas calls this 'as_constant',
and that works like we expect it to - it forces it at compile time
because I'm passing it to a 'consteval' function.
So we were discussing this recently on Twitter and there was some discussion here about
movable and non-movable types between Darrell, myself and Andreas, and I had this idea of making
a thing that did an evaluation of a 'callable' here which led to this idea. (By the way,
before I move on I do suggest that you check out Andreas's book "Programming with C++20 - Concepts,
Coroutines, Ranges and More," which Andreas has available on his website, on Amazon and LeanPub if
you are interested in that.) Okay. So let's get us back to this. The idea that I wanted to generalize
is this thing called 'consteval_invoke',
and it is simply a wrapper around std::invoke that takes a callable and a set of parameters, but it's
'consteval', so it's going to force the compiler to evaluate this thing at compile time. Now I do
intend to make 'consteval_invoke', as simple as it is, part of my utility library that I am currently
putting together as a result of the little snippets from this channel, so be sure to check
out my GitHub page if you are interested in that. But yeah, that is all of the ways that I know of
to force the compiler to do something at compile time; and so it's a general solution here that
is arguably not much different than Andreas's 'as_constant', but perhaps you like one or
the other better. Thank you for watching this episode of C++ Weekly. Be sure to subscribe.