Search code examples
c++reflection

What is the purpose of introducing meta::reflect_value in c++ reflection?


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?


Solution

  • 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.)