std::meta::define_aggregate
| Defined in header <meta>
|
||
template< std::meta::reflection_range R = std::initializer_list<std::meta::info> >
consteval std::meta::info define_aggregate( std::meta::info class_type,
R&& member_dsc );
|
(since C++26) | |
Defines an aggregate type C from a sequence of data member descriptions member_dsc.
Let C denote the type represented by class_type and rk be the K th reflection value in member_dsc.
Let ⊥ (“absurdum symbol” in logic) denote a special value.
For every rk in member_dsc, let the sextuple (Tk, Nk, Ak, Wk, NUAk, ANNk) be the corresponding data member description represented by rk .
A call to this function is a core constant expression [1] if and only if all of the following preconditions are met:
class_typerepresents a cv-unqualified class type;Cis incomplete from every point in the evaluation context; [2]std::meta::is_data_member_spec(rk)istruefor every rk ;std::meta::is_complete_type(Tk)istruefor every rk ; and- for every pair ( rk , rm ) where k < m, if Nk is not ⊥ and Nm is not ⊥, then either:
- Nk is not the same identifier as Nm or
- Nk is the identifier
_(LOW LINE). [3]
- ↑ That is, the function can be evaluated at compile time.
- ↑
Ccan be a class template specialization for which there is a reachable definition of the class template. In this case, the injected declaration is an explicit specialization. - ↑ Every provided identifier is either unique or
"_".
The define_aggregate produces an injected declaration D that defines C and has properties as follows:
- The target scope of D is the scope to which
Cbelongs. - The locus of D follows immediately after the core constant expression currently under evaluation.
- The characteristic sequence of D is the sequence of reflection values rk .
- If
Cis a specialization of a templated class T, andCis not a local class, then D is an explicit specialization of T. - For each rk, there is a corresponding entity Mk with public access belonging to the class scope of D with the following properties:
- If Nk is ⊥, Mk is an unnamed bit-field. Otherwise, Mk is a non-static data member whose name is the identifier Nk .
- The type of Mk is Tk .
- Mk is declared with the attribute
[[no_unique_address]]if and only if NUAk istrue. - If Wk is not ⊥, Mk is a bit-field whose width is that value. Otherwise, Mk is not a bit-field.
- If Ak is not ⊥, Mk has the alignment-specifier
alignas(Ak). Otherwise, Mk has no alignment-specifier. - For every reflection
rin ANNk , Mk has an annotation whose underlying constant isr.
- For every rm in
member_dscsuch that k < m, the declaration corresponding to rk precedes the declaration corresponding to rm .
If C is a specialization of a templated class and it has not been instantiated, C is treated as an explicit specialization.
Parameters
| class_type | - | reflected incomplete class type to complete |
| member_dsc | - | range of data member descriptions to inject |
Return value
class_type that is complete (contains injected members), as described above.
Notes
C can be a union type.
Example
#include <meta>
#include <print>
struct MyAggregate; // declares an incomplete type
consteval
{
// Define the members
std::meta::info members[]
{
std::meta::data_member_spec(^^int, {.name = "id"}),
std::meta::data_member_spec(^^double, {.name = "value"})
};
// Pass the reflection of the incomplete class
std::meta::define_aggregate(^^MyAggregate, members);
}
// MyAggregate is now a complete aggregate type with “id” and “value” fields.
int main()
{
MyAggregate a{.id = 42, .value = 1.618};
std::println("a.id = {}, a.value = {}", a.id, a.value);
}
Output:
a.id = 42, a.value = 1.618
See also
(C++26) |
checks if reflection represents a data member description (function) |
(C++26) |
creates a data member description for use with injected declarations (function) |