Spec-Zone.ru › C++

std::meta::data_member_spec

Определён в заголовке <meta>
consteval std::meta::info
    data_member_spec( std::meta::info type, std::meta::data_member_options options );
(1) (начиная с C++26)
struct data_member_options
{
    std::optional</*name-type*/> name;
    std::optional<int> alignment;
    std::optional<int> bit_width;
    bool no_unique_address = false;
    std::vector<std::meta::info> annotations;
};
(2) (начиная с C++26)
1) Возвращает отражение описания члена данных, которое можно воплотить в член данных класса с помощью std::meta::define_aggregate.
2) Тип параметра data_member_options является агрегатным типом. Он не является структурным типом, и объекты этого типа могут использоваться только во время компиляции.

Описание члена данных обычно представляется в виде шестёрки (T, N, A, W, NUA, ANN), где:

  • T — тип, представленный std::meta::dealias(type).
  • N — либо идентификатор, закодированный в options.name, либо специальное значение (обозначаемое ⊥), если options.name не содержит значения.
  • A — значение выравнивания, хранящееся в options.alignment, либо специальное значение (обозначаемое ⊥), если options.alignment не содержит значения.
  • W — значение, хранящееся в options.bit_width, либо специальное значение (обозначаемое ⊥), если options.bit_width не содержит значения.
  • NUA — значение options.no_unique_address.
  • ANN — последовательность значений std::meta::constant_of(r) для каждого r в options.annotations.

Два описания членов данных равны, если каждый из их соответствующих компонентов является той же сущностью или тем же идентификатором, имеет равное значение либо в обоих случаях равен ⊥. Два отражения описаний членов данных сравниваются на равенство, если описываемые ими описания равны.

Если комбинация аргументов недопустима, генерируется исключение std::meta::exception. Подробности приведены в разделе Исключения ниже.

Тип, обозначенный /*name-type*/ и используемый только для описания, является типом класса со следующими конструкторами:

std::meta::data_member_options::name-type::name-type

template< class T >
    requires std::constructible_from<std::u8string, T>
consteval /*name-type*/( T&& value );
(1)
template< class T >
    requires std::constructible_from<std::string, T>
consteval /*name-type*/( T&& value );
(2)
1) Создаёт имя из строки UTF-8 std::u8string(std::forward<T>(value)).
2) Создаёт имя из строки std::string(std::forward<T>(value)) в обычной кодировке литералов.

Параметры

type - тип определяемого члена данных
options - прочие характеристики определяемого члена данных

Возвращаемое значение

Отражение, представляющее описание члена данных, построенное на основе аргументов.

Исключения

Генерирует std::meta::exception, если не выполняются все следующие условия:

  • std::meta::dealias(type) представляет тип объекта или ссылочный тип.
  • Если options.name содержит значение:
    • Если имя было создано из строки UTF-8, строка является написанием допустимого токена, а токен — допустимым идентификатором при интерпретации в кодировке UTF-8.
    • В противном случае (имя было создано из обычной строки) строка является написанием допустимого токена, а токен — допустимым идентификатором при интерпретации в обычной кодировке литералов.
  • Если options.name не содержит значения, options.bit_width содержит значение. (В этом случае результат описывает безымянное битовое поле.)
  • Если options.bit_width содержит значение V, то:
    • std::meta::is_integral(type) || std::meta::is_enum_type(type) равно true.
    • options.alignment содержит значение.
    • options.no_unique_address равно false.
    • V не является отрицательным.
    • Если V равно нулю, options.name не содержит значения.
  • Если options.alignment содержит значение, оно является допустимым значением выравнивания и не меньше std::meta::alignment_of(type).
  • Для каждого элемента r в options.annotations значение std::meta::type_of(r) допустимо и представляет тип объекта, не являющийся массивом, а вычисление std::meta::constant_of(r) не генерирует исключение.

Пример

#include <format>
#include <meta>
#include <print>
#include <string>

// Defines struct A as if by “struct A { std::string x; };”
struct A;
consteval
{
    std::meta::define_aggregate(^^A,
        {
            std::meta::data_member_spec(^^std::string, {.name = "x"}),
        });
}

// Defines a simple tuple type
template<typename... Ts>
struct Tuple
{
    struct Storage;
    consteval
    {
        std::vector<std::meta::info> member_specs;
        template for (int i{}; auto type : {^^Ts...})
        {
            member_specs.push_back(data_member_spec(type, {.name = std::format("item{}", i)}));
            ++i;
        }

        define_aggregate(^^Storage, member_specs);
    }

    Storage data;

    Tuple(): data{} {}
    Tuple(const Ts& ...values): data{values...} {}
};

int main()
{
    A a;
    a.x = "Hello";

    Tuple<char, char, char, int> t('C', '+', '+', 26);

    std::println("{}, {}{}{}{}!", a.x, t.data.item0, t.data.item1, t.data.item2, t.data.item3);
}

Вывод:

Hello, C++26!

См. также

is_data_member_spec
(C++26)
проверяет, представляет ли отражение описание члена данных
(функция)
define_aggregate
(C++26)
определяет агрегатный тип из последовательности описаний членов данных
(шаблон функции)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/meta/data_member_spec

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API