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.
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<bool>struct X {};
constevalbooloperator<(std::meta::info, X<false>){returnfalse; }constevalvoid g(std::meta::info r, X<false> xv){
r ==^^int&&true; // error: ^^ applies to the type-idint&&
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<true>< xv; // OK} — end example]
If a reflect-expressionR 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; // error: A::S found through using-declaratorstruct C :virtual B {struct S {}; };
struct D :virtual B, C {};
D::S s; // OK, names C::S per [class.member.lookup]constexpr std::meta::info r2 =^^D::S; // OK, result C::S not found through using-declarator — end example]
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 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.
[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>; // OKconstexpr std::meta::info b =^^fn<int>; // error: ambiguousconstexpr std::meta::info c =^^std::vector; // OKtemplate<typename T>struct S {staticconstexpr std::meta::info r =^^T;
using type = T;
};
static_assert(S<int>::r ==^^int);
static_assert(^^S<int>::type !=^^int);
typedefstruct X {} Y;
typedefstruct 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]