Namespaces
Variants

Reflexionsoperator (seit C++26)

Von de.cppreference.net
 
 
C++-Sprache
Allgemeine Themen
Ablaufsteuerung
Bedingte Ausführungsanweisungen
if
Iterationsanweisungen (Schleifen)
for
bereichs-for (C++11)
Sprunganweisungen
Funktionen
Funktionsdeklaration
Lambda-Funktionsausdruck
inline-Spezifizierer
Dynamische Ausnahmespezifikationen (bis C++17*)
noexcept-Spezifizierer (C++11)
Ausnahmen
Namensräume
Typen
Spezifizierer
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Speicherdauerspezifizierer
Initialisierung
Ausdrücke
Alternative Darstellungen
Literale
Boolesche - Ganzzahl - Gleitkomma
Zeichen - Zeichenkette - nullptr (C++11)
Benutzerdefinierte (C++11)
Dienstprogramme
Attribute (C++11)
Typen
typedef-Deklaration
Typalias-Deklaration (C++11)
Umwandlungen
Speicherzuweisung
Klassen
Klassenspezifische Funktionseigenschaften
explicit (C++11)
static

Besondere Memberfunktionen
Templates
Verschiedenes
 
 

Der unäre ^^ Operator, genannt Reflexionsoperator, liefert die Reflexion des gegebenen Sprachkonstrukts vom Typ std::meta::info.

Syntax

^^ :: (1)
^^ Reflexionsname (2)
^^ Typ-ID (3)
^^ ID-Ausdruck (4)
Reflexionsname - ein Bezeichner, optional qualifiziert, optional unter Verwendung des Template-Disambiguators. Diese Form hat Vorrang vor Typ-ID und ID-Ausdruck
Typ-ID - eine Typ-ID
ID-Ausdruck - ein ID-Ausdruck

Die längste Sequenz von Token, die syntaktisch den Operanden von ^^ bilden könnte, wird geparst. Wenn das Ergebnis ein Template darstellt, darf dem Ausdruck nicht direkt < folgen.

static_assert(std::meta::is_type(^^int())); // ^^int() represents the type int()
                                            // not a function call to ^^int

template<bool> struct X {};
consteval bool operator<(std::meta::info, X<false>) { return false; }
consteval void g(std::meta::info r, X<false> xv) {
    r == ^^int && true; // error: ^^ applies to the type-id int&&
    r == ^^int & true; // error: ^^ applies to the type-id int&
    r == (^^int) && true; // OK
    r == ^^int &&&& true; // error: int &&&& is not a valid type-id
    ^^X < xv; // error: reflect-expression that represents a template is followed by <
    (^^X) < xv; // OK
    ^^X<true> < xv; // OK
}

Erklärung

1) Der Ausdruck ^^:: repräsentiert den globalen Namensraum.
2) In ^^reflection-name wird der Reflexionsname nachgeschlagen, und die Darstellung wird wie folgt bestimmt:
  • Wenn die Suche eine Deklaration findet, die einen using-Deklarator ersetzt hat, ist der Ausdruck ungültig.
  • Andernfalls, wenn die Suche einen Namensraumalias, Namensraum oder ein Konzept findet, repräsentiert das Ergebnis diese Entität.
  • Andernfalls, wenn die Suche ein Template findet:
  • Wenn der Template-Disambiguator vorhanden ist, repräsentiert das Ergebnis das Klassentemplate, das durch den eingefügten Klassennamen benannt wird.
  • Andernfalls muss der eingefügte Klassenname, wenn er als Typname betrachtet wird, eindeutig sein (sonst ist der Ausdruck ungültig). Das Ergebnis repräsentiert den so benannten Typ.
  • Andernfalls, wenn die Suche eine Überladungsmenge findet, muss diese Überladungsmenge nur Deklarationen eines eindeutigen Funktionstemplates enthalten. Das Ergebnis repräsentiert dieses Funktionstemplate.
  • Andernfalls, wenn die Suche ein Klassentemplate, Variablentemplate oder Aliastemplate findet, repräsentiert das Ergebnis dieses Template.
  • Andernfalls, wenn die Suche einen Typ-Templateparameter findet, repräsentiert das Ergebnis den Typ des entsprechenden Arguments.
  • Andernfalls, wenn die Suche einen Typedef-Namen oder Typalias findet, repräsentiert das Ergebnis diesen Typalias.
template<typename T>
struct S {
    static constexpr std::meta::info r = ^^T;
    using type = T;
};
static_assert(S<int>::r == ^^int); // OK
static_assert(^^S<int>::type != ^^int); // OK

typedef struct X {} Y;
typedef struct Z {} Z;
constexpr std::meta::info e = ^^Y; // OK, represents the type alias Y
constexpr std::meta::info f = ^^Z; // OK, represents the type alias Z, not the type
  • Andernfalls, wenn die Suche einen Klassentyp oder einen Aufzählungstyp findet, repräsentiert das Ergebnis diesen Typ.
  • Andernfalls, wenn die Suche ein Klassenmember einer anonymen Union findet, repräsentiert das Ergebnis dieses Member.
  • Andernfalls wird der Reflexionsname als ID-Ausdruck betrachtet (siehe Form (4) unten).
3) Der Ausdruck ^^type-id repräsentiert eine Entität, die wie folgt bestimmt wird:
  • Wenn die Typ-ID einen Platzhaltertyp bezeichnet (z.B. auto), ist der Ausdruck ungültig.
  • Andernfalls, wenn die Typ-ID ein Aliastemplate mit einer Templateargumentliste benennt, repräsentiert das Ergebnis den so benannten Typalias. (Andere Formen von Typaliasnamen würden als Reflexionsname behandelt, und das Ergebnis würde ebenfalls den Typalias repräsentieren.)
  • Andernfalls repräsentiert das Ergebnis den durch die Typ-ID bezeichneten Typ.
4) Der Ausdruck ^^id-expression repräsentiert eine Entität, die wie folgt bestimmt wird:
  • Wenn der ID-Ausdruck bezeichnet:
  • eine Variable, die durch eine Lambda-Init-Capture deklariert wurde,
  • eine funktionslokale vordefinierte Variable (__func__),
  • einen lokalen Parameter, der durch einen requires-Ausdruck deklariert wurde, oder
  • eine lokale Entität, bei der ein Lambda-Gültigkeitsbereich zwischen dem Punkt, an dem sie eingeführt wird, und dem Reflexionsausdruck liegt (unabhängig davon, ob die Entität gefangen ist oder nicht),
ist der Ausdruck ungültig.
  • Andernfalls, wenn der ID-Ausdruck eine Überladungsmenge bezeichnet, muss die Überladungsauflösung eine eindeutige Funktion auswählen. Das Ergebnis repräsentiert diese Funktion.
template<typename T> void fn() requires (^^T != ^^int);
template<typename T> void fn() requires (^^T == ^^int);
template<typename T> void fn() requires (sizeof(T) == sizeof(int));
constexpr std::meta::info a = ^^fn<char>; // OK
constexpr std::meta::info b = ^^fn<int>;  // error: ambiguous

Der Operand ist ein nicht ausgewerteter Operand.

Anmerkungen

Ein Reflexionswert kann auch durch std::meta::reflect_constant, std::meta::reflect_object, std::meta::reflect_function oder durch Standardinitialisierung von std::meta::info erzeugt werden. Darüber hinaus kann ein Reflexionswert durch Aufruf von <Meta>-Funktionen mit vorhandenen std::meta::info-Objekten erhalten werden.

Wenn ein Typalias als Teil einer Typ-ID erscheint, bewahrt der Reflexionsoperator den Typalias nicht.

using T = int;
static_assert(^^T != ^^int);
static_assert(^^T& == ^^int&);
static_assert(^^T const == ^^const int);

Beispiel

int arr[] = {1, 2, 3};
auto [a1, a2, a3] = arr;
[[=1]] void fn(int n);
enum Enum { A };
using Alias = int;
struct S { int mem; };
template<auto> struct TCls {};
template<auto> void TFn();
template<auto> int TVar;
template<auto N> using TAlias = TCls<N>;
template<auto> concept Concept = true;
namespace NS {}
namespace NSAlias = NS;

constexpr auto r_arr   = ^^arr; // represents a variable
constexpr auto r_sb    = ^^a3; // represents a structured binding
constexpr auto r_fn    = ^^fn; // represents a function
constexpr auto r_enum  = ^^Enum::A; // represents an enumerator
constexpr auto r_alias = ^^Alias; // represents a type alias
constexpr auto r_type  = ^^S; // represents a type
constexpr auto r_mem   = ^^S::mem; // represents a class member
constexpr auto r_tcls  = ^^TCls; // represents a class template
constexpr auto r_tfn   = ^^TFn; // represents a function template
constexpr auto r_tvar  = ^^TVar; // represents a variable template
constexpr auto r_ttype = ^^TAlias; // represents an alias template
constexpr auto r_cncpt = ^^Concept; // represents a concept
constexpr auto r_ns    = ^^NS; // represents a namespace
constexpr auto r_ns2   = ^^NSAlias; // represents a namespace alias

int main() {}

Siehe auch

gibt eine Reflexion zurück, die einen Wert oder ein Templateparameterobjekt repräsentiert, geeignet zur Verwendung als konstantes Templateargument
(Funktionstemplate)
gibt eine Reflexion zurück, die ein Objekt repräsentiert, geeignet zur Verwendung als konstantes Templateargument
(Funktionstemplate)
gibt eine Reflexion zurück, die eine Funktion repräsentiert, geeignet zur Verwendung als konstantes Templateargument
(Funktionstemplate)