Namespaces
Variants

оператор отражения (начиная с C++26)

С ru.cppreference.net
 
 
Язык C++
Общие темы
Управление потоком
Условные операторы
if
Итерационные операторы (циклы)
for
range-for (C++11)
Операторы перехода
Функции
Объявление функции
Лямбда-выражение
inline спецификатор
Динамические спецификации исключений (до C++17*)
noexcept спецификатор (C++11)
Исключения
Пространства имен
Типы
Спецификаторы
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Спецификаторы продолжительности хранения
Инициализация
Выражения
Альтернативные представления
Литералы
Булев - Целочисленный - С плавающей точкой
Символьный - Строковый - nullptr (C++11)
Пользовательский (C++11)
Утилиты
Атрибуты (C++11)
Типы
typedef объявление
Объявление псевдонима типа (C++11)
Приведения
Выделение памяти
Классы
Свойства функций, специфичные для классов
explicit (C++11)
static

Специальные функции-члены
Шаблоны
Разное
 
Выражения
Общее
Литералы
Операторы
Преобразования
 

Унарный ^^ оператор, называемый оператором отражения, возвращает отражение данной языковой конструкции типа std::meta::info.

Синтаксис

^^ :: (1)
^^ reflection-name (2)
^^ type-id (3)
^^ id-expression (4)
reflection-name - идентификатор, необязательно квалифицированный, необязательно с использованием template disambiguator. Эта форма имеет приоритет над type-id и id-expression
type-id - a type-id
id-expression - an id-expression

Наибольшая последовательность токенов, которая может синтаксически образовывать операнд ^^ разбирается. Если результат представляет шаблон, то за выражением не должен непосредственно следовать <.

static_assert(std::meta::is_type(^^int())); // ^^int() represents the type int()
                                            // not a function call to ^^int

template<bool> struct X {};
consteval bool operator<(std::meta::info, X<false>) { return false; }
consteval void g(std::meta::info r, 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; // 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
}

Объяснение

1) Выражение ^^:: представляет глобальное пространство имен.
2) В ^^reflection-name, reflection-name ищется, и представление определяется следующим образом:
  • Если поиск находит объявление, которое заменило using-declarator, выражение недействительно.
  • В противном случае, если поиск находит namespace alias, namespace, или concept, результат представляет эту сущность.
  • В противном случае, если поиск находит template:
  • Если template disambiguator присутствует, результат представляет шаблон класса, названный injected-class-name.
  • В противном случае, injected-class-name должен быть однозначным при рассмотрении как имя-типа (иначе выражение недействительно). Результат представляет тип, названный таким образом.
  • В противном случае, если поиск находит множество перегрузки, это множество перегрузки должно содержать только объявления единственного шаблона функции. Результат представляет этот шаблон функции.
  • В противном случае, если поиск находит class template, variable template, или alias template, результат представляет этот шаблон.
  • В противном случае, если поиск находит type template parameter, результат представляет тип соответствующего аргумента.
  • В противном случае, если поиск находит typedef name или type alias, результат представляет этот псевдоним типа.
template<typename T>
struct S {
    static constexpr std::meta::info r = ^^T;
    using type = T;
};
static_assert(S<int>::r == ^^int); // OK
static_assert(^^S<int>::type != ^^int); // OK

typedef struct X {} Y;
typedef struct Z {} Z;
constexpr std::meta::info e = ^^Y; // OK, represents the type alias Y
constexpr std::meta::info f = ^^Z; // OK, represents the type alias Z, not the type
  • В противном случае, если поиск находит class type или enumeration type, результат представляет этот тип.
  • В противном случае, если поиск находит член класса anonymous union, результат представляет этот член.
  • В противном случае, reflection-name рассматривается как id-expression (см. форму (4) ниже).
3) Выражение ^^type-id представляет сущность, определяемую следующим образом:
  • Если type-id обозначает placeholder type (например, auto), выражение недействительно.
  • В противном случае, если type-id именует alias template со списком аргументов шаблона, результат представляет именованный таким образом псевдоним типа. (Другие формы имен псевдонимов типа будут рассматриваться как reflection-name, и результат также будет представлять псевдоним типа.)
  • В противном случае, результат представляет тип, обозначаемый type-id.
4) Выражение ^^id-expression представляет сущность, определяемую следующим образом:
  • Если id-expression обозначает:
  • переменную, объявленную init-capture лямбды init-capture,
  • a function-local predefined variable (__func__),
  • a local parameter объявленный requires выражением, или
  • локальную сущность, для которой область лямбды вмешивается между точкой, в которой она введена, и выражением отражения (независимо от того, захвачена сущность или нет),
выражение недействительно.
  • В противном случае, если id-expression обозначает множество перегрузки, overload resolution должно выбрать единственную функцию. Результат представляет эту функцию.
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>; // OK
constexpr std::meta::info b = ^^fn<int>;  // error: ambiguous
  • В противном случае, если id-expression обозначает переменную, structured binding, enumerator, или non-static data member, результат представляет эту сущность.
  • В противном случае (например, id-expression обозначает non-type template parameter или pack indexing выражение), выражение недействительно.

Операнд является unevaluated operand.

Примечания

Значение отражения также может быть получено с помощью std::meta::reflect_constant, std::meta::reflect_object, std::meta::reflect_function, или default-initializing std::meta::info. Кроме того, значение отражения можно получить, вызывая <meta> функции с существующими std::meta::info объектами.

Если псевдоним типа появляется как часть type-id, оператор отражения не сохраняет псевдоним типа.

using T = int;
static_assert(^^T != ^^int);
static_assert(^^T& == ^^int&);
static_assert(^^T const == ^^const int);

Пример

int arr[] = {1, 2, 3};
auto [a1, a2, a3] = arr;
[[=1]] void fn(int n);
enum Enum { A };
using Alias = int;
struct S { int mem; };
template<auto> struct TCls {};
template<auto> void TFn();
template<auto> int TVar;
template<auto N> using TAlias = TCls<N>;
template<auto> concept Concept = true;
namespace NS {}
namespace NSAlias = NS;

constexpr auto r_arr   = ^^arr; // represents a variable
constexpr auto r_sb    = ^^a3; // represents a structured binding
constexpr auto r_fn    = ^^fn; // represents a function
constexpr auto r_enum  = ^^Enum::A; // represents an enumerator
constexpr auto r_alias = ^^Alias; // represents a type alias
constexpr auto r_type  = ^^S; // represents a type
constexpr auto r_mem   = ^^S::mem; // represents a class member
constexpr auto r_tcls  = ^^TCls; // represents a class template
constexpr auto r_tfn   = ^^TFn; // represents a function template
constexpr auto r_tvar  = ^^TVar; // represents a variable template
constexpr auto r_ttype = ^^TAlias; // represents an alias template
constexpr auto r_cncpt = ^^Concept; // represents a concept
constexpr auto r_ns    = ^^NS; // represents a namespace
constexpr auto r_ns2   = ^^NSAlias; // represents a namespace alias

int main() {}

Смотри также

возвращает отражение, представляющее значение или template parameter object, подходящее для использования в качестве константного аргумента шаблона
(шаблон функции)
возвращает отражение, представляющее объект, подходящее для использования в качестве константного аргумента шаблона
(шаблон функции)
возвращает отражение, представляющее функцию, подходящее для использования в качестве константного аргумента шаблона
(шаблон функции)