std::meta::data_member_spec
| Definiert in Header <meta>
|
||
consteval std::meta::info
data_member_spec( std::meta::info type, std::meta::data_member_options options );
|
(1) | (seit 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) | (seit C++26) |
data_member_options ist ein Aggregattyp. Er ist kein struktureller Typ, und Objekte dieses Typs können nur zur Compilezeit verwendet werden.Eine Datenmemberbeschreibung wird üblicherweise als Sextupel (T, N, A, W, NUA, ANN) dargestellt, wobei:
- T der durch
std::meta::dealias(type)dargestellte Typ ist. - N entweder der durch
options.namekodierte Bezeichner oder ein spezieller Wert (mit ⊥ bezeichnet) ist, fallsoptions.namekeinen Wert enthält. - A der durch
options.alignmentgehaltene Ausrichtungswert oder ein spezieller Wert (mit ⊥ bezeichnet) ist, fallsoptions.alignmentkeinen Wert enthält. - W der durch
options.bit_widthgehaltene Wert oder ein spezieller Wert (mit ⊥ bezeichnet) ist, fallsoptions.bit_widthkeinen Wert enthält. - NUA der Wert von
options.no_unique_addressist. - ANN die Sequenz der Werte
std::meta::constant_of(r)für jedesrinoptions.annotationsist.
Zwei Datenmemberbeschreibungen sind gleich, wenn jede ihrer jeweiligen Komponenten dieselben Entitäten, dieselben Bezeichner, gleiche Werte sind oder beide ⊥ sind. Zwei Reflexionen von Datenmemberbeschreibungen vergleichen sich als gleich, wenn die Beschreibungen, die sie darstellen, gleich sind.
Wenn die Kombination von Argumenten ungültig ist, wird std::meta::exception geworfen. Siehe den Abschnitt Ausnahmen unten für Details.
Der nur zur Darstellung verwendete Typ, der durch /*name-type*/ bezeichnet wird, ist ein Klassentyp mit den folgenden Konstruktoren:
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) | |
std::u8string(std::forward<T>(value)).std::string(std::forward<T>(value)) in der gewöhnlichen Literalkodierung.Parameter
| type | - | der Typ des zu definierenden Datenmembers |
| options | - | weitere Merkmale des zu definierenden Datenmembers |
Rückgabewert
Eine Reflexion, die eine Datenmemberbeschreibung darstellt, konstruiert aus den Argumenten.
Ausnahmen
Wirft std::meta::exception, sofern nicht alle der folgenden Bedingungen erfüllt sind:
std::meta::dealias(type)stellt einen Objekttyp oder einen Referenztyp dar.- Wenn
options.nameeinen Wert enthält:
- Wenn der Name aus einer UTF-8-Zeichenkette konstruiert wurde, ist die Zeichenkette die Schreibweise eines gültigen Tokens und das Token ist ein gültiger Bezeichner, wenn es mit UTF-8 interpretiert wird.
- Andernfalls (der Name wurde aus einer gewöhnlichen Zeichenkette konstruiert) ist die Zeichenkette die Schreibweise eines gültigen Tokens und das Token ist ein gültiger Bezeichner, wenn es mit der gewöhnlichen Literalkodierung interpretiert wird.
- Wenn
options.namekeinen Wert enthält, enthältoptions.bit_widtheinen Wert. (In diesem Fall beschreibt das Ergebnis ein unbenanntes Bitfeld.) - Wenn
options.bit_widtheinen Wert V enthält, dann:
std::meta::is_integral(type) || std::meta::is_enum_type(type)ist wahr.options.alignmententhält einen Wert.options.no_unique_addressist falsch.- V ist nicht negativ.
- Wenn V Null ist, enthält
options.namekeinen Wert.
- Wenn
options.alignmenteinen Wert enthält, ist er ein gültiger Ausrichtungswert und nicht kleiner alsstd::meta::alignment_of(type). - Für jedes Element
rinoptions.annotationsiststd::meta::type_of(r)gültig und stellt einen Nicht-Array-Objekttyp dar, und die Auswertung vonstd::meta::constant_of(r)wirft keine Ausnahme.
Beispiel
#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);
}
Ausgabe:
Hello, C++26!
Siehe auch
(C++26) |
prüft, ob Reflexion eine Datenmemberbeschreibung darstellt (Funktion) |
(C++26) |
definiert einen Aggregattyp aus einer Sequenz von Datenmemberbeschreibungen (Funktionstemplate) |