The codebase I work on nowadays is heavily optimized. In that spirit, functions often taken bool
or enum
template arguments and then use if constexpr
to branch on them. The point is, we can ensure that in tight loops where we process millions of items, the function really only has code that’s actually needed. For example:
template<bool use_filter> void foo(Items& items) {
if constexpr (use_filter) {
if (!filter(items)) return;
}
process(items);
}
Obviously, the actual functions are way more involved, but the above example demonstrates how this is used. Problem is, now we have code that looks like this:
if (query.use_filter()) {
foo<true>(items);
} else {
foo<false>(items);
}
It’s actually much worse, as we have often multiple template arguments so the if-forest grows quite large. What’s intriguing is that what I really would like to write is foo<query.use_filter()>(items)
. That is, somehow tell C++ to turn a runtime value into a template argument by implementing the branching automatically under the hood. Yes, it’s code explosion, but we’re already doing that. It’s possible to use macros to achieve this (to some extent), but it gets quite ugly quick. It’d be better not to use macros.