Two months ago I published “the hidden compile-time cost of C++26 reflection”, where I measured what including <meta> and doing some basic reflection actually costs per translation unit. If you haven’t read it, start there – this post builds directly on top of it.
That article used a prerelease GCC 16 snapshot. Since then, GCC 16 has been officially released and is now widely available, which seemed like a good excuse to revisit the topic with a more realistic example: enum-to-string conversion.
Enum-to-string is the “hello world” of reflection – but it’s also genuinely useful in real projects, for things like logging, serialization, debugging, and so on. If you adopt reflection in a real codebase, it might be the first thing you’ll write.
So: how much does reflection-based enum-to-string actually cost, in compile time, compared to the alternatives?
the three approaches
I benchmarked three implementations of the same operation: given an enum value, return a std::string_view with its enumerator name.
1. reflection (c++26)
No macros, no boilerplate, works for any enum:
#include <meta> #include <string_view> #include <type_traits> template < typename T > requires std:: is_enum_v < T > is_enum_v constexpr std:: string_view to_enum_string ( T val ) string_view to_enum_stringT val { template for ( constexpr auto e : std:: define_static_array ( std:: meta::enumerators_of (^^ T ))) define_static_arraymeta::enumerators_of { if ( val == [: e :]) val return std:: meta::identifier_of ( e ); meta::identifier_of } return "<unknown>" ; }
The code was taken from “What the heck is Reflection?” by Murat Hepeyiler. I think it’s a pretty idiomatic example.
... continue reading