Using C++23s constexpr unique_ptr
Back in 2022, my paper P2273R3: Making std::unique_ptr constexpr was accepted for C++23. All the time, I planned to provide an implementation for libc++ but never found the time. Recently, I discovered that somebody else was so kind and implemented my paper.
Time to show you when a constexpr unique_ptr
helps you.
An example
This is an example from my C++20 book Programming with C++20 - Concepts, Coroutines, Ranges, and more.
What I want to illustrate is a very rough sketch of a car racing game. I have a couple of different car brands and a factory function capable of creating a car, returning a base pointer:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
Later somewhere in the game, I want to determine the fastest car available. Assume that a car could be broken or require maintenance, some reason for it to be less fast than initially or not present at all. Therefore I have the function FastestCar
, which walks over the set of cars and returns the index of the fastest available car at the moment.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
While, of course, most use will be during run-time, there are two use cases for FastestCar
at compile-time.
Doing something at compile-time
Suppose you want to check, at compile-time, that the fastest car is a specific one. Or, alternatively, you want to determine the fastest car such that you can render this image at compile-time as part of the boot screen of the game. Let's use the first scenario.
1 2 3 4 5 6 |
|
Above I use FastestCar
in a static_assert
to verify that Tesla
is the fastest available car. While this entire code works, the implementation of FastestCar
is the issue.
Oh no, raw pointers
If you look closer at it, you can see that I use a raw pointer car
that holds the result of CreateCar
. Due to that raw pointer, I also require a matching delete
. But that's pre-C++11-like code. I teach stop using raw pointers, and yet I have to show examples and write code that uses raw pointers.
C++23 to rescue
Luckily in C++23, I have a better solution thanks to P2273. I can now switch to a unique_ptr
and eliminate the raw pointers in CreateCar
in favor of std::make_unique
at the same time.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
My code now looks like normal code but is constexpr-able. I hope P2273 simplifies your life and code as well!
If you want to know why I'm a fan of constexpr
functions, you might find my post constexpr functions: optimization vs guarantee helpful.
Andreas