std::meta::data_member_spec
来自 zh.cppreference.net
| 定义于头文件 <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 具现化为类的数据成员。
一个数据成员描述通常表示为六元组 (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!
参见
(C++26) |
检查反射是否表示数据成员描述 (函数) |
(C++26) |
从数据成员描述序列定义聚合类型 (函数模板) |