C++17中如何借助getAllFields()自动合并类成员元组?
解决C++17反射中自动合并类实例成员元组的问题
你只需要修改getAllFields_pair函数的对应代码段,借助getAllFields()返回的成员元组,通过std::apply遍历并配对两个实例的成员,不需要直接引用具体成员变量名。修改后的代码如下:
class B{public: int c1; std::string c2; float c3; constexpr auto getAllFields() { return std::tie(c1, c2, c3); } static auto getAllFields_pair(B& b1, B& b2) { ///vvv insert your code here // but please don't call c1/c2/c3 by variable names directly auto tie1 = b1.getAllFields(); auto tie2 = b2.getAllFields(); return std::apply( [&tie2](auto&&... members1) { return std::apply( [&members1...](auto&&... members2) { return std::make_tuple(std::make_tuple(members1, members2)...); }, tie2 ); }, tie1 ); ///^^^ edit (only) here } static void copyIntAndFloatToB2(B& b1, B& b2) { auto f=[](auto& b1_cx,auto& b2_cx){ using typee=std::remove_reference_t<decltype(b1_cx)>; if constexpr(std::is_same_v<typee,int> || std::is_same_v<typee,float>){ b2_cx= b1_cx; } }; std::apply( [&f](auto&&... aField) { ( f(std::get<0>(aField),std::get<1>(aField)) , ...); }, getAllFields_pair(b1,b2) ); } };
代码逻辑说明
- 获取成员元组:调用两个
B实例的getAllFields(),得到包含所有成员引用的元组tie1和tie2(std::tie返回的是成员的引用元组,后续操作直接关联原实例的成员)。 - 遍历并配对成员:
- 外层
std::apply遍历tie1的所有成员,展开为参数包members1...; - 内层
std::apply遍历tie2的所有成员,展开为参数包members2...; - 通过C++17折叠表达式
std::make_tuple(members1, members2)...,把两个元组对应位置的成员配对成子元组,最终组合成和原手动实现结构一致的大元组。
- 外层
- 适配性:后续如果
B类新增或修改成员,只要同步更新getAllFields(),getAllFields_pair会自动适配,无需手动修改成员变量名。
验证效果
原测试代码依然可以正常运行,扩展测试float类型也能生效:
int main(){ B b1; B b2; b1.c1=5; b1.c3=3.14f; B::copyIntAndFloatToB2(b1,b2); std::cout<<b2.c1<<std::endl; // 输出5 std::cout<<b2.c3<<std::endl; // 输出3.14 }
内容的提问来源于stack exchange,提问作者cppBeginner
相关产品推荐
相关产品推荐

