Skip to content

Latest commit

 

History

History
117 lines (74 loc) · 4.04 KB

File metadata and controls

117 lines (74 loc) · 4.04 KB

Reflection (C++ 26)

Zurück


Quellcode


Inhalt


Allgemeines


Hinweis

Das C++ 26 Reflection-API wird aktuell von Microsoft Visual C++ nicht unterstützt.

Es gibt für den Compiler Explorer (Godbolt) einen Link, der eine spezielle Umgebung bereitstellt, in der man den aktuellen Stand der Reflection-API Entwicklung testen und ausprobieren kann:

https://compiler-explorer.com/z/M4KjvfM9M


Erste Schritte

Durch Reflection bekommt C++ zwei neue Operatoren:

Der Reflection-Operator ^^

Der Reflexionsoperator erzeugt einen so genannten „Reflexionswert” aus seinem Operanden, zum Beispiel ^^int oder ^^char:

Beispiel:

constexpr auto r = ^^int;

Ein Reflexionswert ist eine Darstellung von Programmelementen als konstanter Ausdruck.

Reflexionswerte können von Typen, Aufzählungen, Funktionen etc. gebildet werden.

Hinweis:
Dieses Beispiel mit dem Doppel-Caret (^^int) entspricht der aktuellen Syntax für C++ 26. Das Gegenstück mit dem einzelnen Caret (^int) war ein alter Entwurf und ist im standardisierten C++ 26 nicht mehr gültig.

Richtig und final für den C++ 26 – Standard ist stattdessen die Anweisung mit dem Doppel-Caret (^^), informell auch „Cat-Ears-” oder „Unibrow”-Operator genannt.

Der Splice-Operator [: ... :]

Unter Splicing versteht man den Vorgang, bei dem eine Reflexionswert wieder in echten C++-Code umgewandelt wird.

Ist r eine Reflection einer Entität, so fügt [:r:] die entsprechende Entität (bzw. den Ausdruck oder Typ) an dieser Stelle in das Programm ein.

Beispiel:

01: constexpr auto r = ^^int;
02: typename[:r:] x = 123;        // same as: int x = 123;
03: typename[:^^char:] c = '*';   // same as: char c = '*';
04: 
05: static_assert(std::same_as<decltype(x), int>);
06: static_assert(std::same_as<decltype(c), char>);
07: assert(x == 123);
08: assert(c == '*');

Man kann sich das wie „Quote” (^^) und „Unquote” ([: :]) vorstellen – jedoch direkt in die Sprache integriert.


Weitere Beispiele

Im folgenden sind eine Reihe von Textdateien mit Reflection-Beispielen vorhanden:

Reflection_00: Beispiel aus Compiler Explorer
Reflection_01: Simple Example
Reflection_02: Enum -> String und Enum -> String
Reflection_03: std::meta::members_of

Erläuterungen zum Beispiel „Enum -> String und Enum -> String”:

  • ^^E: Reflektiert den Typ der Enumeration (holt die Metadaten in den Compiler).
  • std::meta::identifier_of(e): Liefert zur Compilezeit den exakten Namen des Enumerators als Text zurück.
  • [:e:] (Splicer): Wandelt das Metadaten-Objekt e wieder zurück in echten C++-Code um – in diesem Fall wird daraus der echte Wert (z. B. Color::Red) an die Stelle im Code eingesetzt.

Literaturhinweise

Die elementaren Erläuterungen der grammatikalischen Spracherweiterungen stammen aus dem Blog von Rainer Grimm: Programmiersprache C++: Reflection in C++26.

Eine ganze Serie von Beispielen zu diesem Thema findet sich in einer Artikelserie von Andreas Müller. Die Serie startet mit diesem Artikel, die Folgeartikel sind am Ende des ersten Artikels mit der Überschrift „C++ with Reflection – A whole new language – Part 1: From enum to string ... and back again” am Ende aufgeführt.

Der Quellcode der Artikelserie wird auch durch ein Github-Repository cpp_reflection_blog begleitet.


Zurück