From cppreference.com
The unary ^^ operator, called the reflection operator, yields the reflection of the given language construct, of type
.
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
, and the representation is determined as follows:
If lookup finds a declaration that replaced a
, the expression is invalid.
Otherwise, if lookup finds a
,
, or
, the result represents that entity.
Otherwise, if lookup finds a
:
If lookup finds a
:
If the
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
,
, or
, the result represents that template.
Otherwise, if lookup finds a type
, the result represents the type of the corresponding argument.
Otherwise, if lookup finds a
or
, 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
or an
, the result represents that type.
Otherwise, if lookup finds a class member of an
, 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
(e.g. auto), the expression is invalid.
Otherwise, if the type-id names an
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
,
a
function-local predefined variable
(__func__),
a
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,
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,
,
, or
, the result represents that entity.
Otherwise (e.g. the id-expression denotes a non-type
or a
expression), the expression is invalid.
The operand is an
.
Notes
A reflection value can also be produced by
,
,
, or
std::meta::info. In addition, a reflection value can be obtained by calling
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
(C++26)
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
(C++26)
returns a reflection representing a value or
, suitable for use as a constant template argument
(function template)
(C++26)
returns a reflection representing an object, suitable for use as a constant template argument
(function template)
(C++26)
returns a reflection representing a function, suitable for use as a constant template argument
(function template)