[expr.reflect]
7 Expressions [expr]
7.6 Compound expressions [expr.compound]
7.6.2 Unary expressions [expr.unary]
7.6.2.10 The reflection operator [expr.reflect]
The unary ^^ operator, called the reflection operator, yields a prvalue of type std::meta::info ([basic.fundamental]).
[Note 1:
This document places no restriction on representing, by reflections, constructs not described by this document or using the names of such constructs as operands of reflect-expressions.
— end note]
A reflect-expression is parsed as the longest possible sequence of tokens that could syntactically form a reflect-expression.
An unparenthesized reflect-expression that represents a template shall not be followed by <.
[Example 1: static_assert(std::meta::is_type(^^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; r == ^^int & true; r == (^^int) && true; r == ^^int &&&& true; ^^X < xv; (^^X) < xv; ^^X<true> < xv; } — end example]
A reflect-expression of the form ^^:: represents the global namespace.
If a reflect-expression R matches the form ^^reflection-name, it is interpreted as such; the identifier is looked up and the representation of R is determined as follows:
[Example 2: struct A { struct S {}; }; struct B : A { using A::S; }; constexpr std::meta::info r1 = ^^B::S; struct C : virtual B { struct S {}; }; struct D : virtual B, C {}; D::S s; constexpr std::meta::info r2 = ^^D::S; — end example]
Otherwise, if lookup finds a namespace alias ([namespace.alias]), R represents that namespace alias.
Otherwise, if lookup finds a namespace ([basic.namespace]), R represents that namespace.
Otherwise, if lookup finds a concept ([temp.concept]), R represents the denoted concept.
Otherwise, if lookup finds a template ([temp.names]), the representation of R is determined as follows:
If lookup finds an injected-class-name ([class.pre]), then:
Otherwise, if lookup finds an overload set, that overload set shall contain only declarations of a unique function template F; R represents F.
Otherwise, if lookup finds a type alias A, R represents the underlying entity of A if A was introduced by the declaration of a template parameter; otherwise, R represents A.
Otherwise, if lookup finds a class or an enumeration, R represents the denoted type.
Otherwise, if lookup finds a class member of an anonymous union ([class.union.anon]), R represents that class member.
A reflect-expression R of the form ^^type-id represents an entity determined as follows:
A reflect-expression R of the form ^^id-expression represents an entity determined as follows:
Otherwise, if the id-expression denotes an overload set S, overload resolution for the expression &S with no target shall select a unique function ([over.over]); R represents that function.
Otherwise, if the id-expression denotes a variable, structured binding, enumerator, or non-static data member, R represents that entity.
Otherwise, R is ill-formed.
[Example 3: 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>; constexpr std::meta::info b = ^^fn<int>; constexpr std::meta::info c = ^^std::vector; template<typename T> struct S { static constexpr std::meta::info r = ^^T; using type = T; }; static_assert(S<int>::r == ^^int); static_assert(^^S<int>::type != ^^int); typedef struct X {} Y; typedef struct Z {} Z; constexpr std::meta::info e = ^^Y; constexpr std::meta::info f = ^^Z; — end example]