Heise 17.03.2026
11:00 Uhr

Programmiersprache C++26: Reflexion zur Kompilierungszeit


C++26 kommt und führt unter anderem die Kompilierungszeit‑Reflexion ein, die einige Aufgaben vereinfacht, ohne auf Makros zurückgreifen zu müssen.

Programmiersprache C++26: Reflexion zur Kompilierungszeit

Im heutigen Beitrag meines C++-Blogs möchte ich über C++26 und eine der wahrscheinlich wirkungsvollsten Funktionen schreiben, die dem Arbeitsentwurf hinzugefügt wurden. Auch wenn C++26 noch ein paar Wochen bis zur offiziellen Fertigstellung braucht, wissen wir seit dem WG21-Sommertreffen im Juni 2025, was in C++26 enthalten sein wird.

Der neue Standard wird viele spannende Verbesserungen bringen, aber die wahrscheinlich größte Veränderung ist die Reflexion (Reflection) zur Kompilierungszeit! In Sofia hat das Standardisierungs-Komitee sieben Reflection-Papiere für C++26 angenommen:

Die verlinkten Beiträge bieten genügend theoretischen Lesestoff.

Die wichtigste Frage ist: Was kannst du mit dieser neuen Funktion machen? Einige haben bereits ihre Ideen veröffentlicht.

Steve Downey hat ein Beispiel, das eine JSON-Zeichenkette zur Kompilierungszeit analysiert und daraus C++-Objekte erstellt. Der direkte Link zum Compiler Explorer lautet godbolt.org/z/YsEK418K6.

Das zweite Beispiel stammt von Jason Turner und ermöglicht es, Bindungen zu anderen Sprachen zu generieren. Der direkte Link zum Compiler Explorer lautet godbolt.org/z/6Y17EG984.

Ich finde beide Beispiele prima, aber will auch ein eigenes zeigen. Das Problem, das ich jahrelang zu lösen versucht habe und das auch in verschiedenen Schulungen und sogar in meinem eigenen Buch Programming with C++20 – Concepts, Coroutines, Ranges, and more auftaucht. Ich musste die bittere Pille schlucken, einen nicht so tollen Code zu zeigen.

Ich rede von Enums und nicht davon, wie man ein Enum in einen String konvertiert und umgekehrt. Der Code dafür ist übrigens in den oben verlinkten Beiträgen zu finden.

Nein, ich hab mindestens noch ein anderes Problem mit Enums: Iteration. Wie oft wollte ich schon über ein enum iterieren. Es gibt Lösungen, die meist makrobasiert und mit vielen Regeln sind. Zum Beispiel nur aufeinanderfolgende Zahlen und ein letztes Mitglied namens Last oder MAX. Aber was ist, wenn es Lücken in einem enum gibt? Wie

Genau, dann greift die Regel, dass nicht aufeinanderfolgende Nummerierungen nicht erlaubt sind.

Folgender Code zeigt einen Ansatz, der anderen Sprachen wie C# ähnelt, in denen das Iterieren der enum-Werte ohne weitere Umstände möglich ist:

Ich habe in #A eine Hilfsvariable erstellt, einfach weil es für sich schon hilfreich ist, die Anzahl der Werte in einem enum zu ermitteln.

Die Implementierung für die Aufgabe selbst befindet sich dann in #B. Du kannst dir eine andere Implementierung ausdenken, die für größere Enums besser geeignet ist, aber diese hier ist schön kurz und bündig.

Die Utility-Funktion sieht in Aktion nicht besonders aus, und man merkt nicht, dass im Hintergrund eine Reflexion stattfindet:

Wie du siehst, gibt #B den stark typisierten Enum-Wert zurück. Deshalb ist std::to_underlying erforderlich, wenn der Wert mit std::print verwendet wird. Das ist eine Designentscheidung: Der Code bleibt so lange wie möglich stark typisiert.

Es gibt noch weitere Designüberlegungen, beispielsweise ob get_enum_values auch eine Variable sein sollte, da sie für jeden Typ konstant ist.

An dieser Stelle werde ich nicht alle neuen Teile erklären, da ich nur zeigen möchte, was mit C++26 möglich ist.

Den vollständigen Code zum Experimentieren findest du im Compiler Explorer.

P.S.: Falls du dich fragst, ob die Implementierung von #B für ein leeres enum, welches ein std::array der Größe Null ergibt, korrekt ist, lautet die Antwort: Ja, der Code ist korrekt. Einer der Vorteile von std::array ist, dass es einen Sonderfall für den Fall der Größe Null gibt. Ein Array im C-Stil wäre nicht gültig.

(rme)