reflection operator (since C++26) - cppreference.com

From cppreference.com

The unary ^^ operator, called the reflection operator, yields the reflection of the given language construct, of type

std::meta::info

.

Syntax

^^ ::(1) ^^reflection-name(2) ^^type-id(3) ^^id-expression(4) The longest sequence of tokens that could syntactically form the operand of ^^ is parsed. If the result represents a template, the expression must not be directly followed by <.

static_assert(std::meta::is_type(^^int()));// ^^int() represents the type int()// not a function call to ^^inttemplate<bool>structX{};constevalbooloperator<(std::meta::info,X<false>){returnfalse;}constevalvoidg(std::meta::infor,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;// OKr==^^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}Explanation

1) The expression ^^:: represents the global namespace.

2) In ^^reflection-name, the reflection-name is

looked up

, and the representation is determined as follows:

If lookup finds a declaration that replaced a

using-declarator

, the expression is invalid.

Otherwise, if lookup finds a

namespace alias

,

namespace

, or

concept

, the result represents that entity.

Otherwise, if lookup finds a

template

:

If lookup finds a

injected-class-name

:

If the

template disambiguator

is present, the result represents the class template named by the injected-class-name.

Otherwise, the injected-class-name must be unambiguous when considered as a type-name (otherwise the expression is invalid). The result represents the type so named.

Otherwise, if lookup finds an overload set, that overload set must contain only declarations of a unique function template. The result represents that function template.

Otherwise, if lookup finds a

class template

,

variable template

, or

alias template

, the result represents that template.

Otherwise, if lookup finds a type

template parameter

, the result represents the type of the corresponding argument.

Otherwise, if lookup finds a

typedef name

or

type alias

, the result represents that type alias.

template<typenameT>structS{staticconstexprstd::meta::infor=^^T;usingtype=T;};static_assert(S<int>::r==^^int);// OKstatic_assert(^^S<int>::type!=^^int);// OKtypedefstructX{}Y;typedefstructZ{}Z;constexprstd::meta::infoe=^^Y;// OK, represents the type alias Yconstexprstd::meta::infof=^^Z;// OK, represents the type alias Z, not the typeOtherwise, if lookup finds a

class type

or an

enumeration type

, the result represents that type.

Otherwise, if lookup finds a class member of an

anonymous union

, the result represents that member.

Otherwise, the reflection-name is considered an id-expression (see form (4) below).

3) The expression ^^type-id represents an entity determined as follows:

If the type-id designates a

placeholder type

(e.g. auto), the expression is invalid.

Otherwise, if the type-id names an

alias template

with a template argument list, the result represents the type alias so named. (Other form of type alias names would be treated as a reflection-name, and the result would also represent the type alias.)

Otherwise, the result represents the type denoted by the type-id.

4) The expression ^^id-expression represents an entity determined as follows:

If the id-expression denotes:

a variable declared by a lambda's

init-capture

,

a

function-local predefined variable

(__func__),

a

local parameter

declared by a requires expression, or

a local entity for which a lambda scope intervenes between the point at which it is introduced and the reflect expression (whether the entity is captured or not),

the expression is invalid.Otherwise, if the id-expression denotes an overload set,

overload resolution

must select a unique function. The result represents that function.

template<typenameT>voidfn()requires(^^T!=^^int);template<typenameT>voidfn()requires(^^T==^^int);template<typenameT>voidfn()requires(sizeof(T)==sizeof(int));constexprstd::meta::infoa=^^fn<char>;// OKconstexprstd::meta::infob=^^fn<int>;// error: ambiguousOtherwise, if the id-expression denotes a variable,

structured binding

,

enumerator

, or

non-static data member

, the result represents that entity.

Otherwise (e.g. the id-expression denotes a non-type

template parameter

or a

pack indexing

expression), the expression is invalid.

The operand is an

unevaluated operand

.

Notes

A reflection value can also be produced by

std::meta::reflect_constant

,

std::meta::reflect_object

,

std::meta::reflect_function

, or

default-initializing

std::meta::info. In addition, a reflection value can be obtained by calling

<meta>

functions with existing std::meta::info objects.

If a type alias appears as part of a type-id, the reflection operator does not preserve the type alias.

usingT=int;static_assert(^^T!=^^int);static_assert(^^T&==^^int&);static_assert(^^Tconst==^^constint);Notes

Feature-test macro ValueStdFeature

__cpp_impl_reflection

202506L

(C++26)

Reflection

Example

Run this code

intarr[]={1,2,3};auto[a1,a2,a3]=arr;[[=1]]voidfn(intn);enumEnum{A};usingAlias=int;structS{intmem;};template<auto>structTCls{};template<auto>voidTFn();template<auto>intTVar;template<autoN>usingTAlias=TCls<N>;template<auto>conceptConcept=true;namespaceNS{}namespaceNSAlias=NS;constexprautor_arr=^^arr;// represents a variableconstexprautor_sb=^^a3;// represents a structured bindingconstexprautor_fn=^^fn;// represents a functionconstexprautor_enum=^^Enum::A;// represents an enumeratorconstexprautor_alias=^^Alias;// represents a type aliasconstexprautor_type=^^S;// represents a typeconstexprautor_mem=^^S::mem;// represents a class memberconstexprautor_tcls=^^TCls;// represents a class templateconstexprautor_tfn=^^TFn;// represents a function templateconstexprautor_tvar=^^TVar;// represents a variable templateconstexprautor_ttype=^^TAlias;// represents an alias templateconstexprautor_cncpt=^^Concept;// represents a conceptconstexprautor_ns=^^NS;// represents a namespaceconstexprautor_ns2=^^NSAlias;// represents a namespace aliasintmain(){}See also

splice specifiers

template for

(C++26)

returns a reflection representing a value or

template parameter object

, suitable for use as a constant template argument
(function template)

[edit]

(C++26)

returns a reflection representing an object, suitable for use as a constant template argument
(function template)

[edit]

(C++26)

returns a reflection representing a function, suitable for use as a constant template argument
(function template)

[edit]