C++无成员名获取类/结构体成员:实现方案与前景问询
C++通过字符串获取类成员的问题解答
1. 是否已有现成库可实现该需求?
有几个成熟的第三方库可以满足需求:
- Boost.PFR:针对聚合类型,支持通过编译期索引访问成员,在C++20及以上配合支持的编译器,可通过
pfr::get_name获取成员名称,还能通过decltype(pfr::get<I>(obj))推导成员类型。你可以遍历所有成员索引,匹配目标字符串后获取对应成员的名称、值和类型,不需要提前知晓成员信息。 - magic_get:与Boost.PFR原理类似,提供编译期获取聚合类型成员名称、类型的能力,可自行实现字符串匹配逻辑来定位成员。
- 实验性反射库:部分编译器(如GCC)提供了基于反射提案的实验性实现,可直接通过字符串查询类成员,但语法尚未标准化。
2. 反射是否是解决该问题的方案?
是的,原生反射正是这类问题的终极解决方案。它能让程序在编译期或运行时直接查询类型的成员信息(名称、类型、内存布局等),并通过字符串直接访问对应成员,无需依赖第三方库的编译期元编程技巧。
目前第三方库的实现本质是用模板、宏或编译器扩展模拟反射能力:在编译期生成成员名称与访问器的映射表,运行时通过查表匹配字符串来获取成员。这和未来原生反射的核心逻辑一致,但受限于静态类型特性,仅支持聚合类型或需提前用宏声明的类。
3. 若当前无法实现,何时能支持该能力?
原生反射已纳入C26的核心提案范围,Herb Sutter等标准成员正在推进相关工作。如果进展顺利,C26将正式加入std::reflect相关接口,提供完整的类型反射能力,包括通过名称访问类成员。
在此之前,部分编译器已提供实验性支持(如GCC的-freflect选项),可以提前体验反射功能,但语法和最终标准可能存在差异。
示例实现(基于Boost.PFR)
#include <boost/pfr.hpp> #include <string> #include <iostream> #include <typeinfo> struct MyStruct { int id; std::string name; double score; }; template <typename T> void retrieve_member(T& obj, const std::string& target_name) { constexpr std::size_t member_count = boost::pfr::tuple_size_v<T>; // 编译期遍历所有成员索引 auto search = [&]<std::size_t... I>(std::index_sequence<I...>) { ( (boost::pfr::get_name<I, T>() == target_name ? (std::cout << "成员名称: " << boost::pfr::get_name<I, T>() << "\n成员值: " << boost::pfr::get<I>(obj) << "\n成员类型: " << typeid(decltype(boost::pfr::get<I>(obj))).name() << '\n', true) : false) || ... ); }; search(std::make_index_sequence<member_count>{}); } int main() { MyStruct s{101, "Alice", 95.5}; retrieve_member(s, "name"); retrieve_member(s, "score"); }
内容的提问来源于stack exchange,提问作者Robert Shepherd
相关产品推荐
相关产品推荐

