Files
cppdraft_translate/cppdraft/expr/reflect.md
2025-10-25 03:02:53 +03:00

13 KiB
Raw Blame History

[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]

reflect-expression:
^^ ::
^^ reflection-name
^^ type-id
^^ id-expression

reflection-name:
nested-name-specifieropt identifier
nested-name-specifier template identifier

1

#

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]

2

#

The component names of a reflection-name are those of its nested-name-specifier (if any) and its identifier.

The terminal name of a reflection-name of the formnested-name-specifier template identifier shall denote a template.

3

#

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())); // ^^ applies to the type-id int()template struct X {};consteval bool operator<(std::meta::info, X) { return false; }consteval void g(std::meta::info r, X 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 < xv; // OK} — end example]

4

#

A reflect-expression of the form ^^:: represents the global namespace.

5

#

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:

when considered as a type-name andR represents the class template specialization so named.

  • (5.5.2)

    Otherwise, if lookup finds an overload set, that overload set shall contain only declarations of a unique function template F;R represents F.

  • (5.5.3)

    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]

  • (5.6)

    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.

  • (5.7)

    Otherwise, if lookup finds a class or an enumeration,R represents the denoted type.

  • (5.8)

    Otherwise, if lookup finds a class member of an anonymous union ([class.union.anon]), R represents that class member.

  • (5.9)

    Otherwise, the reflection-name shall be an id-expression I and R is ^^I (see below).

6

#

A reflect-expression R of the form^^type-id represents an entity determined as follows:

7

#

A reflect-expression R of the form^^id-expression represents an entity determined as follows:

a variable declared by an init-capture ([expr.prim.lambda.capture]),

a function-local predefined variable ([dcl.fct.def.general]),

a local parameter introduced by a requires-expression ([expr.prim.req]), or

a local entity E ([basic.pre]) for which a lambda scope intervenes between the point at which E was introduced and R,

then R is ill-formed.

  • (7.2)

    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.

  • (7.3)

    Otherwise, if the id-expression denotes a variable, structured binding, enumerator, or non-static data member,R represents that entity.

  • (7.4)

    Otherwise, R is ill-formed. [Note 3: This includes unqualified-ids that name a constant template parameter andpack-index-expressions. — end note]

The id-expression of a reflect-expression is an unevaluated operand ([expr.context]).

[Example 3: template void fn() requires (^^T != ^^int);template void fn() requires (^^T == ^^int);template void fn() requires (sizeof(T) == sizeof(int));

constexpr std::meta::info a = ^^fn; // OKconstexpr std::meta::info b = ^^fn; // error: ambiguousconstexpr std::meta::info c = ^^std::vector; // OKtemplatestruct S {static constexpr std::meta::info r = ^^T; using type = T;};static_assert(S::r == ^^int);static_assert(^^S::type != ^^int);

typedef struct X {} Y;typedef struct Z {} Z;constexpr std::meta::info e = ^^Y; // OK, represents the type alias Yconstexpr std::meta::info f = ^^Z; // OK, represents the type alias Z, not the type ([basic.lookup.general]) — end example]