3 ms·
[C++20] 60 LOC constexpr get_name for members / no ifdefs / Clang,GCC,msvc
- kris-jusiak 3y agoResources: - https://reddit.com/r/cpp/comments/1890jr9/reflectcpp_automatic_field_name_extraction_from/ https://reddit.com/r/cpp/comments/1890jr9/reflectcpp_automat... - https://www.reddit.com/r/cpp/comments/18b8iv9/c20_to_tuple_with_compiletime_names/ https://www.reddit.com/r/cpp/comments/18b8iv9/c20_to_tuple_w... Auto-tuning version of constexpr get_name for members struct foo { int bar; int baz; }; static_assert("bar"sv == get_name<0, foo>); static_assert("baz"sv == get_name<1, foo>); Basic idea: template <auto Ptr> [[nodiscard]] consteval auto get_name() -> std::string_view { return std::source_location::current().function_name(); } template <class T> extern const T external; // magic happens here constexpr auto ptr(auto&& t) { auto&& [p1] = t; return &p1; } struct foo { int field; }; std::cout << get_name<ptr(external<foo>)>(); // prints ...field... Auto-tuning the name (to avoid ifdefs for compilers): // define a $struct$.$filed$ to find the parsing requirements for given compiler struct $struct$ { int $field$; // pick some name / $ is valid identifier now }; constexpr auto $name = get_name_impl<0, struct$>; constexpr auto $end = $name.substr($name.find("$field$") + sizeof("$field$") - 1); constexpr auto $begin = $name[$name.find("$field$") - 1]; template <auto N, class T> constexpr auto get_name = [] { const auto name = get_name_impl<N, T>; const auto begin = name.find(end); const auto tmp = name.substr(0, begin); return tmp.substr(tmp.find_last_of(begin) + 1); }(); Full example - https://godbolt.org/z/MWhf6voTs https://godbolt.org/z/MWhf6voTs