Namespaces
Variants

std::meta::data_member_spec

来自 zh.cppreference.net
< cpp | 元
 
 
 
反射库
 
反射类型和查询
反射查询
反射布局查询
类型属性
类型属性查询
 
定义于头文件 <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!

参见

检查反射是否表示数据成员描述
(函数)
从数据成员描述序列定义聚合类型
(函数模板)