Reflection tutorial - #146
Conversation
78421b5 to
449e861
Compare
449e861 to
d88c703
Compare
dfc0352 to
1ee1e03
Compare
1ee1e03 to
7b843bd
Compare
4827585 to
4ac10e1
Compare
4ac10e1 to
3a2459f
Compare
2d2ddfe to
ad90164
Compare
ad90164 to
91ce8a7
Compare
RyanJK5
left a comment
There was a problem hiding this comment.
Really happy with how this came out. It keeps the relevant parts of reflection in clear focus.
| // We use `throw` inside a `consteval` block rather than `static_assert` | ||
| // or `EXPECT_*`: `static_assert` needs `members` to independently be a | ||
| // constant expression, and `EXPECT_*`'s comparison helpers aren't | ||
| // `constexpr` functions. |
There was a problem hiding this comment.
This code probably do with a one-sentence explanation of what a consteval block is.
| // `e` is a loop variable, not a constant expression, so we can't | ||
| // splice it with `return [:e:];`. `extract<Suit>(e)` only needs a | ||
| // value, not a fixed compile-time constant. | ||
| return extract<Suit>(e); |
There was a problem hiding this comment.
I really like how naturally this was introduced.
| TEST(TutorialsReflection, Substitute) { | ||
| // `substitute(^^Template, {args...})` instantiates a template from infos; | ||
| // `reflect_constant` turns an ordinary value into an info usable as a | ||
| // non-type template argument. | ||
| // clang-format off | ||
| constexpr std::meta::info array_info = | ||
| substitute(^^std::array, {^^double, std::meta::reflect_constant(3)}); | ||
| // clang-format on | ||
|
|
||
| static_assert(std::is_same_v<typename[:array_info:], std::array<double, 3>>); | ||
| } |
There was a problem hiding this comment.
I think this could benefit from a comment explaining the use case of substitute - when you want to use a reflection in a consteval context even though it itself is not a constant expression.
For me, at least, I found the distinction between constant expressions and consteval to be one of the more difficult topics when first learning reflection.
| constexpr std::ranges::range auto member_functions = std::define_static_array( | ||
| members_of(^^Point, std::meta::access_context::current()) | | ||
| std::views::filter([](std::meta::info member) { | ||
| return is_function(member) && has_identifier(member); | ||
| })); | ||
|
|
There was a problem hiding this comment.
nit: I would prefer to write this as two separate filters, but I'm more than happy to approve whatever you or others find more readable. (below code is not clang-formatted)
constexpr std::ranges::range auto member_functions = std::define_static_array(
members_of(^^Point, std::meta::access_context::current())
| std::views::filter(std::meta::is_function)
| std::views::filter(std::meta::has_identifier));
No description provided.