I am reading P2996 (https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2996r2.html) paper which introduces reflection in c++ language. There are some examples showing how to use those features. In example 3.2 we have following code:
consteval auto member_number(int n) {
return std::meta::nonstatic_data_members_of(^S)[n];
}
But in example 3.14 there is:
std::vector args = {^To, ^From};
for (auto mem : nonstatic_data_members_of(^From)) {
args.push_back(reflect_value(mem));
}
My question is why do we need to use reflect_value in the second example? When we have to use that function in general case and how we could know that product of nonstatic_data_members_of on not enough?
In the second example,
mem is a std::meta::info that reflects a non-static data member of From.reflect_value(mem) is a std::meta::info that reflects the value of mem. (That is, [:reflect_value(mem):] == mem.)Remember that substitute operates on the reflected entities (e.g. substitute(^std::tuple, {^int}) is ^std::tuple<int>, not ^std::tuple<^int> which is invalid anyway). In the example, get_struct_to_tuple_helper wants to substitute into
template <typename To, typename From, std::meta::info ... members>
constexpr auto struct_to_tuple_helper(From const& from) -> To
So the arguments to substitute (after ^To and ^From) must reflect std::meta::info values (not just be such values), which necessitates the use of reflect_value.
(By the way, it seems that reflect_value got renamed to reflect_result in P2996R3, but the main functionality is unchanged.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With