Я читаю документ P2996 (https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2996r2.html), в котором представлено отражение на языке C++. Есть несколько примеров, показывающих, как использовать эти функции. В примере 3.2 у нас есть следующий код:
consteval auto member_number(int n) {
return std::meta::nonstatic_data_members_of(^S)[n];
}
Но в примере 3.14 есть:
std::vector args = {^To, ^From};
for (auto mem : nonstatic_data_members_of(^From)) {
args.push_back(reflect_value(mem));
}
Мой вопрос: почему нам нужно использовать reflect_value
во втором примере? Когда нам нужно использовать эту функцию в общем случае и как мы можем знать, что произведения nonstatic_data_members_of
недостаточно?
Во втором примере
mem
— это std::meta::info
, который отражает нестатический элемент данных From
.reflect_value(mem)
— это std::meta::info
, который отражает значение mem
. (То есть [:reflect_value(mem):] == mem
.)Помните, что substitute
работает с отраженными объектами (например, substitute(^std::tuple, {^int})
— это ^std::tuple<int>
, а не ^std::tuple<^int>
, что в любом случае недопустимо). В примере get_struct_to_tuple_helper
хочет заменить на
template <typename To, typename From, std::meta::info ... members>
constexpr auto struct_to_tuple_helper(From const& from) -> To
Таким образом, аргументы substitute
(после ^To
и ^From
) должны отражать значения std::meta::info
(а не просто быть такими значениями), что требует использования reflect_value
.
(Кстати, похоже, что reflect_value
переименовали в reflect_result
в P2996R3, но основной функционал остался неизменным.)
Теперь всё чисто и ясно! Спасибо. Размышления будут мощным инструментом, я с нетерпением жду, когда это предложение будет принято.