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-idint()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-idint&
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]
[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 namespace alias ([namespace.alias]),
all declarations found by name lookup shall have the same target scope, and
R represents the namespace alias.
Otherwise,
all declarations found by name lookup shall have the same target scope, and
R represents the type alias.
[Example 3: namespace A {using T =int;
}namespace B {using T =int;
}usingnamespace A;
usingnamespace B;
auto r =^^T; // error: lookup finds type aliases with different target scopes — end example]
Otherwise, if the id-expression denotes an overload set S,
the expression &id-expression shall be well-formed
when considered as an unevaluated operand,
except that the function F selected as described in [over.over]
may be deleted ([dcl.fct.def.delete]);
R represents F.
[Example 4: 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]