如何合理调用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
相关产品推荐
相关产品推荐

