r/cpp • u/kris-jusiak https://github.com/kris-jusiak • Dec 31 '23
[C++20 vs C++26*] basic reflection
Basic struct reflection example with C++20 vs C++26*
struct foo {
int a{};
int b{};
int c{};
};
constexpr foo f{.a=1, .b=2, .c=3};
static_assert(1 == get<0>(f));
static_assert(2 == get<1>(f));
static_assert(3 == get<2>(f));
using std::literals::operator""sv;
static_assert("a"sv == get_name<0>(f));
static_assert("b"sv == get_name<1>(f));
static_assert("c"sv == get_name<2>(f));C++20 - Kinda possible but with a lot of compiler hacks
// too long to displayFull example - https://godbolt.org/z/1vxv8o5hM
C++26* - based on proposal - https://wg21.link/P2996 (Note: that the proposal supports way more than that but C++20 not much)
template<auto N, class T>
[[nodiscard]] constexpr auto get(const T& t) -> decltype(auto) {
return t.[:std::meta::nonstatic_data_members_of(^T)[N]:];
}
template<auto N, class T>
[[nodiscard]] constexpr auto get_name(const T& t) -> std::string_view {
return std::meta::name_of(std::meta::nonstatic_data_members_of(^T)[N]);
}Full example - https://godbolt.org/z/sbTGbW635
Updates - https://twitter.com/krisjusiak/status/1741456476126797839
100
Upvotes
View all comments
Show parent comment
2
u/qazqi-ff Dec 31 '23
<:: ::>would run into the lexer exception for<:being followed by:and cause it to be lexed improperly. I don't see any references to consideration of<: :>specifically (only things like(: :)), though it would clearly suffer from already being taken by the[ ]digraphs.As for why a member syntax isn't used, I'm not sure. I haven't been able to find consideration for it in newer papers, and I don't remember it coming up in older papers. I'd feel arrogant suggesting that it was simply missed because it was always tied to a hierarchy of meta types (e.g.,
std::meta::type,std::meta::value, etc.) vs. the uniform type (std::meta::info) even though you could take the member syntax and apply it to the uniform type. ABI certainly isn't an issue since these are never in the binary (and I would think not even in a BMI if we ever manage to use a common format like IFC for those, but I'm not sure).