You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)
      );
   }
};

代码逻辑说明

  1. 获取成员元组:调用两个B实例的getAllFields(),得到包含所有成员引用的元组tie1和tie2(std::tie返回的是成员的引用元组,后续操作直接关联原实例的成员)。
  2. 遍历并配对成员:
    • 外层std::apply遍历tie1的所有成员,展开为参数包members1...;
    • 内层std::apply遍历tie2的所有成员,展开为参数包members2...;
    • 通过C++17折叠表达式std::make_tuple(members1, members2)...,把两个元组对应位置的成员配对成子元组,最终组合成和原手动实现结构一致的大元组。
  3. 适配性:后续如果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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 12:23:25