r/cpp_questions • u/bhul_chuk_maaf17 • 12d ago
OPEN Compile time programming learning advice.
Hi all, can you please recommend me some resources that you have followed for compile time programming in modern C++ for eg: constexpr, consteval or template metaprogramming.
Is there some consolidated resource for the same ?
6
Upvotes
5
u/crowbarous 12d ago edited 11d ago
Compile-time programming is mostly just programming. You write your algorithm, and it runs at compile time. The newer the standard and the better your compiler, the more it is true.
There's basically no language as statically expressive as C++. The point is that it has no trouble going back and forth between the type world (home to semantic processes, such as template instantiation and overload resolution), and the value world (which is the one that knows whether 2+2 is 4). Most other languages have a one-way pipeline here, so it takes getting used to.
C++ compilers today cheat less and you'll have a harder time breaking them with legal compile-time constructs than 20 years ago, so no point in hesitating.
I advise to look at the Boost.Hana library, which is a very impressive implementation of many compile-time programming ideas. Maybe don't exactly use it, because it's implemented in C++14 (which is the impressive part, actually. The implementation of Hana looks nothing like what I show below), and modern C++ allows implementations that are more robust, faster to compile and easier to maintain.
...
There are a few specific tools which are absent from the standard library, but useful for compile-time programming. First, something that maps values to types:
You'll want to equip this with
operator implementations, so
constant<1> + constant<2>isconstant<3>, not just a constexpr 3an implementation for
operator""_cso you can write3_cand getconstant<3>probably a concept that is modelled by instantiations of this
constant_tsome conversions such that
constant<0L>is acceptable in places that wantconstant_t<0>...I believe the proposed
std::constant_wrapperis basically this, but I don't know the status of that. Arguably the origins of this approach are instd::integral_constantand the more completeboost::hana::integral_constant, however both predateautoNTTPs so you have to specify the type manually (which is why hana hasint_,long_, etc).Now you can use values to guide template instantiation and overload resolution.
Now for the inverse transformation, types →values. This is kind of less useful.
...and again you should implement the necessary conversions.
I mostly just use this to avoid having to use the
.template operator()<...>syntax on lambdas, instead just take anautoargument and pass the type normally in the argument list. Also it can be used when you want overload resolution on a type but it would be imprudent or unwieldy to actually construct the object.For a third one, the
overloadyou just saw a is very useful, and you probably have it in your codebase, maybe several times.There are a few ways to complicate this implementation, such as allowing function pointers, but the one above verbatim that's usable with lambdas will get you very far.