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

如何利用带可变参数的C++模板实现结构体成员的自动批量赋值?

实现结构体成员自动赋值的C++模板方案

当然可以用C++模板来实现这种结构体成员的自动赋值!针对你的场景,我们可以通过模板配合成员指针映射的方式,实现编译期的批量赋值,既减少重复代码,又保证和手动赋值一样的效率。下面提供两种实用的方案:

方案一:通用模板+成员指针映射(灵活适配不同结构体)

这个方案的核心是定义通用的赋值模板,然后通过成员指针对来指定源结构体和目标结构体的成员映射关系,适用于成员名称不完全一致的场景(比如你的例子里absolute_altidue_m和absolute_altitude_m,即便存在笔误,模板依然能处理)。

#include <utility>

// 单个成员的赋值工具函数
template <typename SourceT, typename DestT>
void assign_single_member(DestT& dest, const SourceT& src,
                          auto dest_member_ptr, auto src_member_ptr) {
    dest.*dest_member_ptr = src.*src_member_ptr;
}

// 批量赋值的模板函数,利用C++17折叠表达式遍历所有成员对
template <typename SourceT, typename DestT, typename... MemberPairs>
void assign_members(DestT& dest, const SourceT& src, MemberPairs&&... pairs) {
    (assign_single_member(dest, src, std::get<0>(pairs), std::get<1>(pairs)), ...);
}

// 针对你的两个结构体,特化赋值逻辑
template <>
void assign_members<mavsdk::Telemetry::Position, mavsdk_interface::gpsPos>(
    mavsdk_interface::gpsPos& dest,
    const mavsdk::Telemetry::Position& src) {
    // 定义源和目标的成员映射对:(目标成员指针, 源成员指针)
    assign_members(dest, src,
        std::make_pair(&mavsdk_interface::gpsPos::latitude_deg, &mavsdk::Telemetry::Position::latitude_deg),
        std::make_pair(&mavsdk_interface::gpsPos::longitude_deg, &mavsdk::Telemetry::Position::longitude_deg),
        std::make_pair(&mavsdk_interface::gpsPos::absolute_altidue_m, &mavsdk::Telemetry::Position::absolute_altitude_m),
        std::make_pair(&mavsdk_interface::gpsPos::relative_altitude_m, &mavsdk::Telemetry::Position::relative_altitude_m)
    );
}

使用方式

在你的订阅回调里,直接调用模板函数即可完成自动赋值:

void subcribePosition(ros::Publisher& posGPS_pub, mavsdk::Telemetry & telemetry){
    telemetry.subscribe_position([&](mavsdk::Telemetry::Position pos){
        mavsdk_interface::gpsPos msg;
        // 一键完成所有成员赋值
        assign_members(msg, pos);
        posGPS_pub.publish(msg);
    });
}

方案二:简化版(成员名称一致时)

如果你的两个结构体成员名称完全一致(比如修正笔误后absolute_altitude_m匹配),可以用宏配合模板来进一步简化代码:

// 宏定义单个成员赋值
#define ASSIGN_MEMBER(dest, src, member) dest.member = src.member

// 针对特定结构体的赋值模板
template <>
void assign_members<mavsdk::Telemetry::Position, mavsdk_interface::gpsPos>(
    mavsdk_interface::gpsPos& dest,
    const mavsdk::Telemetry::Position& src) {
    ASSIGN_MEMBER(dest, src, latitude_deg);
    ASSIGN_MEMBER(dest, src, longitude_deg);
    ASSIGN_MEMBER(dest, src, absolute_altitude_m);
    ASSIGN_MEMBER(dest, src, relative_altitude_m);
}

优势说明

  • 编译期完成所有赋值逻辑,没有运行时额外开销,和手动赋值效率完全相同
  • 扩展性强:如果后续需要处理其他结构体对,只需要新增assign_members的特化版本,添加对应的成员映射即可
  • 减少重复代码,避免手动赋值时可能出现的遗漏或笔误

内容的提问来源于stack exchange,提问作者InKronos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 12:02:35