C++26 Reflections adventures and compile time UML

https://news.ycombinator.com/rss Hits: 17
Summary

The first thing I do every time I need to learn a new codebase is to start drawing the UML diagram of its classes, and usually give up soon after I started. The process of doing it manually is certainly useful, but now with reflections I figure it would be fun to try generate it instead. With C++26 reflections[1] the general consensus is that the magnitude of language change is comparable to what happened with C++11. After my little experiment with it, I would cautiously agree. So how does one go about creating a (Plant)UML diagram at compile time? With something like this. With the spoilers out of the way let’s dig in the details. P2996[1] introduces a couple of operators, namely lift ^^ and splice [: :]. The first one “lifts” a type or variable into a “meta” space, and the “splice” one (which imho should have been called “grounding operator”) does the opposite. The first thing to understand is that regardless of what we apply the lift operator (^^) to, it creates a std::meta::info type. This means that some info objects will be reflections of types, and some will be reflections of values. This creates confusion in my head, as at times one needs to check which kind of info something is, but there are good reasons for this and are well explained in section 2.2 of the paper. With that in mind let’s start coding. int main() { MyClass s; constexpr const char* const dot_graph_uml = make_class_graph<MyClass>(); std::cout << dot_graph_uml << std::endl; } You’ll notice right away there is an ugly, and seemingly avoidable char pointer. Let’s get back to that later. Not much happens in main() besides us calling function template that is just a wrapper for what we actually care about: template<typename U> consteval const char* make_class_graph() { std::string graph = "@startuml \nskinparam linetype ortho \n"; std::vector<std::meta::info> already_drawn; graph += make_class_graph_impl(^^U, already_drawn); graph += "@enduml"; return std::define_static_string(graph); } Here we se...

First seen: 2025-08-03 02:16

Last seen: 2025-08-03 18:19