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

如何合理调用ROS中接收const&参数的subscribe重载函数

关于ROS NodeHandle subscribe重载的优化调用方式

针对你提到的ros::NodeHandle中接收void(const Msg&)签名函子的subscribe重载(模板参数M未被使用的版本),目前没有官方提供的无需伪造模板参数的调用方式——因为模板参数M未出现在函数参数列表中,编译器无法自动推导,必须显式指定。

不过可以通过封装辅助函数来简化调用,避免手动传入占位模板参数:

方案1:显式指定消息类型的辅助函数

#include <ros/ros.h>
#include <utility>

template <typename MsgType, typename Callback>
ros::Subscriber subscribe_msg_ref(ros::NodeHandle& nh, const std::string& topic, uint32_t queue_size, Callback&& callback,
                                  const ros::VoidConstPtr& tracked_obj = ros::VoidConstPtr(),
                                  const ros::TransportHints& hints = ros::TransportHints()) {
    // 转发到目标重载,自动填充占位模板参数
    return nh.subscribe<void, const MsgType&>(topic, queue_size, std::forward<Callback>(callback), tracked_obj, hints);
}

调用方式:

// 无需手动写void占位参数,只需指定MsgType
auto sub = subscribe_msg_ref<MsgType>(nh, "/your_topic", 10, [](const MsgType& msg) {
    // 消息处理逻辑
    ROS_INFO("Received message: %d", msg.data);
});

方案2:自动推导消息类型的辅助函数

如果希望完全不用显式指定消息类型,可以通过提取回调的参数类型来自动推导:

#include <ros/ros.h>
#include <utility>
#include <functional>
#include <type_traits>

template <typename Callback>
auto subscribe_msg_ref(ros::NodeHandle& nh, const std::string& topic, uint32_t queue_size, Callback&& callback,
                       const ros::VoidConstPtr& tracked_obj = ros::VoidConstPtr(),
                       const ros::TransportHints& hints = ros::TransportHints()) {
    // 提取回调的参数类型(仅适配接收单个const Msg&参数的回调)
    using CallbackFunc = decltype(&Callback::operator());
    using ArgType = typename std::remove_reference_t<typename std::function<CallbackFunc>::argument_type>;

    return nh.subscribe<void, ArgType>(topic, queue_size, std::forward<Callback>(callback), tracked_obj, hints);
}

调用方式:

// 无需指定任何模板参数,编译器自动推导消息类型
auto sub = subscribe_msg_ref(nh, "/your_topic", 10, [](const MsgType& msg) {
    ROS_INFO("Received message: %d", msg.data);
});

原重载的局限性说明

原重载的模板设计存在缺陷:模板参数M未被使用,导致编译器无法自动推导,必须显式传入占位类型(如void)。这种设计是ROS早期版本的遗留问题,后续版本仍未修正,因此只能通过上述辅助函数的方式优化调用体验。

内容的提问来源于stack exchange,提问作者Fantastic Mr Fox

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 16:55:26