Boost Hana:如何将结构体成员类型转为std::string集合?
Great question! Boost Hana doesn’t include a ready-made typesToString or typeId function matching your exact request, but its robust metaprogramming toolkit lets you build these utilities easily—with all logic happening at compile time. Let’s walk through how to implement both features.
1. Get the Type Name of a Single Variable (typeId)
Boost Hana provides hana::type_name<T>, which returns a compile-time string literal with the type’s name. We can wrap this to create your typeId function:
#include <boost/hana.hpp> #include <string> namespace hana = boost::hana; template <typename T> std::string typeId(const T&) { // Convert Hana's compile-time string to a std::string return std::string{hana::type_name<T>()}; } // Usage example int main() { int x; std::string tName = typeId(x); std::cout << tName << std::endl; // Outputs "int" (varies slightly by compiler) }
Note: The exact string output depends on your compiler—GCC/Clang will return concise names like "int", while MSVC might include more verbose formatting, but the core type name will always be present.
2. Collect Struct Member Type Names (typesToString)
To iterate over a struct’s members without knowing their names, we first need to adapt the struct to Boost Hana’s Struct concept using BOOST_HANA_ADAPT_STRUCT. Then we can use hana::members to get a tuple of the struct’s members, transform each member to its type, and convert those types to strings.
Here’s the full implementation:
#include <boost/hana.hpp> #include <array> #include <string> #include <iostream> namespace hana = boost::hana; // Helper: Get compile-time type name string template <typename T> constexpr auto get_type_name() { return hana::type_name<T>(); } // Helper: Convert compile-time string literal to std::string template <typename Char, std::size_t N> std::string to_std_string(const Char (&str)[N]) { return std::string(str, N - 1); // Trim the trailing null terminator } // Main function to collect struct member type names template <typename Struct> auto typesToString(const Struct& s) { // Get a tuple of the struct's member types auto member_types = hana::transform(hana::members(s), [](auto member) { return hana::type_c<decltype(member)>; }); // Convert each type to a std::string auto type_strings = hana::transform(member_types, [](auto type) { using Type = typename decltype(type)::type; return to_std_string(get_type_name<Type>()); }); // Convert Hana's tuple to a std::array (compile-time size) return hana::to<std::array<std::string, hana::size(member_types)>>(type_strings); } // Adapt your struct to Hana's Struct concept struct MyType { int i; std::string s; bool b; }; BOOST_HANA_ADAPT_STRUCT(MyType, i, s, b); // Usage example int main() { MyType t{}; auto ls = typesToString(t); for (const auto& name : ls) { std::cout << name << std::endl; } // Typical output (GCC): // int // std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> // bool }
Key Notes:
- No member names required:
hana::membersautomatically retrieves all members of the adapted struct, so you don’t need to hardcode any member identifiers. - Compile-time safety: The size of the
std::arrayis determined at compile time based on the number of struct members—no dynamic allocation or runtime checks needed. - Simplifying type names: If you want shorter names (like
"string"instead of the fullstd::stringtype), you’ll need to add string-processing logic to strip namespace qualifiers. This can be done with compiler-specific macros or custom string parsing (e.g., finding the last::in the type name and taking the substring after it).
内容的提问来源于stack exchange,提问作者И..

