[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, the injected-class-name shall be unambiguous when considered as a type-name and R represents the class template specialization so named.

    • 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 class template, variable template, or alias template, R represents that template.

      [Note 2:

      Lookup never finds a partial or explicit specialization.

      — end note]

  • 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:

  • Otherwise, R represents the type denoted by the type-id.

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]