I have the following code, and I can not flatten the nested range using std::views::join
template<typename T>
consteval auto get_names() {
using get_fn = decltype(
[] {
auto result_view = std::meta::bases_of(^^T, std::meta::access_context::unchecked())
| std::views::transform([](std::meta::info r) {
return std::meta::members_of(r, std::meta::access_context::unchecked());
})
// JOIN does not work
// | std::views::join
;
// show range can be flattened
static_assert(std::is_same_v<std::meta::info,
std::remove_cvref_t<decltype(result_view.front().front())>>);
assert(1 == std::ranges::distance(result_view.begin(), result_view.end()));
// return placeholder
return std::vector<int> {1,2,3,4};
});
return get_fn{}().size();
}
When I uncomment join (and static_assert) I get a long error(godbolt link). Am I doing something wrong or should this work?
what seems to be most important part of the error:
/opt/compiler-explorer/clang-bb-p2996-trunk-20250623/bin/../include/c++/v1/meta:663:12: note: subexpression not valid in a constant expression
663 | return __metafunction(detail::__metafn_get_begin_member_decl_of,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
664 | reflectedEntity, ^^sentinel);
An info
returned from bases_of
represents a direct base class relationship. You can't ask for its members - that's not a well-formed question.
You need to ask for the members of the bass class type instead:
return std::meta::members_of(type_of(r), std::meta::access_context::unchecked());
(and then you'll get 8 of them in return, so the assert needs to be adjusted).
The reason this shows up when you use join
is that join
's begin
need to inspect the elements of the underlying range to figure out where the first inner element is. When you just have transform
, neither begin
nor distance
need to apply the transform, so the erroneous call is not evaluated.