最近读别人的代码,看到了一个有意思的东西。

主要是当我们订阅一个消息时候,会调用一个返回函数。

例如:

ros::Subscriber scan_sub=n.subscribe<std_msgs::Int8>("/test", 10, multiprint);

  

这样multiprint函数应该包含一个参数,即

void  multiprint(const std_msgs::Int8::ConstPtr& msg){}

但是,如果我们想要多参数传入的话,就需要使用boost库中的bind函数。例如,当我们的回调函数是这样的:

void  multiprint(const std_msgs::Int8::ConstPtr& msg, int& x, int& y){}

  

Boost::bind    

 在STL中,我们经常需要使用bind1st,bind2st函数绑定器和fun_ptr,mem_fun等函数适配器,这些函数绑定器和函数适配器使用起来比较麻烦,需要根据是全局函数还是类的成员函数,是一个参数还是多个参数等做出不同的选择,而且有些情况使用STL提供的不能满足要求,所以如果可以我们最好使用boost提供的bind,它提供了统一的接口,提供了更多的支持,比如说它增加了shared_ptr,虚函数,类成员的绑定。

 bind并不是一个单独的类或函数,而是非常庞大的家族,依据绑定的参数的个数和要绑定的调用对象的类型,总共有数十种不同的形式,编译器会根据具体的绑定代码制动确定要使用的正确的形式,bind的基本形式如下:

1 template<class R,class F> bind(F f);
2 template<class R,class F,class A1> bind(F f,A1 a1);
3 namespace
4 {
5 boost::arg<1> _1;
6 boost::arg<2> _2;
7 boost::arg<3> _3;
8 …..                                     //其他6个占位符
9 };

  bind接收的第一个参数必须是一个可调用的对象f,包括函数函数指针函数对象、和成员函数指针,之后bind最多接受9个参数参数数量必须与f的参数数量相等,这些参数被传递给f作为入参。 绑定完成后,bind返回一个函数对象,它内部保存了f的拷贝,具有operator()返回值类型自动推导f的返回类型。在发生调用时这个函数对象将把之前存储的参数转发给f完成调用。例如,有一个函数func,它的形式是:

1 func(a1,a2);

那么,他将等价于一个具有无参operator()的bind函数对象调用:

1 bind(func,a1,a2)();

  这是bind最简单的形式,bind表达式存储了func和a1、a2的拷贝,产生了一个临时函数对象。因为func接收两个参数,而a1和a2的拷贝传递给func完成真正的函数调用。

  bind的真正威力在于它的占位符,它们分别定义为_1,_2,_3,一直到 _9,位于一个匿名的名字空间。占位符可以取代bind参数的位置,在发生调用时接受真正的参数占位符的名字表示它在调用式中的顺序,而在绑定的表达式中没有没有顺序的要求,_1不一定必须第一个出现,也不一定只出现一次,例如:

1 bind(func,_2,_1)(a1,a2);

  返回一个具有两个参数的函数对象,第一个参数将放在func的第二个位置,而第二个参数则放在第一个位置,调用时等价于:

1 func(a2,a1);

  

  占位符的最常见的使用方法就是printf中%f,%d等等这些的使用方法。

例程    

  下面是一个简单的订阅消息的例程,在只传入单个变量的时候如下:

#include <ros/ros.h>
#include <std_msgs/Int8.h>int index1=0;
int index2=0;
void  multiprint(const std_msgs::Int8::ConstPtr msg, int& x, int& y)
{printf("%d",*msg);printf("%d \r\n",x);printf("%d \r\n",y);
}
void  multiprint(const std_msgs::Int8::ConstPtr& msg)
{printf("%d \r\n",*msg);
}int main(int argc, char **argv)
{ros::init(argc, argv, "multi_callback");ros::NodeHandle n;ros::NodeHandle private_nh("~");int  rate;private_nh.param("rate",rate, 40);// ros::Subscriber scan_sub=n.subscribe<std_msgs::Int8>("/test", 10, boost::bind(&multiprint, _1, index1, index2));ros::Subscriber scan_sub=n.subscribe<std_msgs::Int8>("test", 10, multiprint);ros::Rate r(rate);while(n.ok()){ros::spinOnce();r.sleep();}return 0;
}

  当通过rostopic传入消息的时候,

rostopic pub /test std_msgs/Int8 "data: 12"

  subscrib函数选择回调,

void  multiprint(const std_msgs::Int8::ConstPtr& msg)
{printf("%d \r\n",*msg);
}

  输出的结果就应该是消息的输入,即

12

  

  当程序改变为:

#include <ros/ros.h>
#include <std_msgs/Int8.h>int index1=0;
int index2=0;
void  multiprint(const std_msgs::Int8::ConstPtr msg, int& x, int& y)
{printf("%d",*msg);printf("%d \r\n",x);printf("%d \r\n",y);
}
void  multiprint(const std_msgs::Int8::ConstPtr& msg)
{printf("%d \r\n",*msg);
}int main(int argc, char **argv)
{ros::init(argc, argv, "multi_callback");ros::NodeHandle n;ros::NodeHandle private_nh("~");int  rate;private_nh.param("rate",rate, 40);ros::Subscriber scan_sub=n.subscribe<std_msgs::Int8>("/test", 10, boost::bind(&multiprint, _1, index1, index2));// ros::Subscriber scan_sub=n.subscribe<std_msgs::Int8>("test", 10, multiprint);ros::Rate r(rate);while(n.ok()){ros::spinOnce();r.sleep();}return 0;
} 

  注意:方程中的消息的参数类型后面一定要跟上::ConstPtr,否则会报错。消息的前面因为是_1占位符传入,所以回调函数里参数调用的msg前不能加&。

  同样通过rostopic传入消息,这样地话运行时回调用

void  multiprint(const std_msgs::Int8::ConstPtr& msg, int& x, int& y)
{printf("%d",*msg);printf("%d \r\n",x);printf("%d \r\n",y);
}

其中

boost::bind(&multiprint, _1, index1, index2)

的_1部分,是后面的获得的消息的传入。

其返回结果应该是

1200

这样就可以在回调函数中传入多个参数了。

C++使用boost::bind 订阅消息中的返回函数传入多个参数相关推荐

  1. http://www.dewen.net.cn/q/16222/C++排序中的sort函数第三个参数的疑问

    C++排序中的sort函数第三个参数的疑问 唐图 3 票 37 #include<stdio.h> #include<string.h> #include<algorit ...

  2. VB中的mid函数的功能及参数

    VB中的mid函数的功能及参数 1.来自MSDN Mid 函数 返回 Variant (String),其中包含字符串中指定数量的字符. 语法 Mid(string, start[, length]) ...

  3. validate中remote返回函数中+号导致submitHandler无法执行

    validate中remote返回函数中+号导致submitHandler无法执行 这是2017年以来我遇到的最无语的bug,现在暂时还没想到原因,但是这个错误真的很无语. 这是我的validate中 ...

  4. HTML调用Java函数或语句,在动态THML语句中调用JS函数传递带空格参数的问题

    刚刚遇到一个问题,调用js函数的参数里带空格,造成调用失败的问题. 部分代码如下: html+=" "; //name中如果有空格就是调用失败 html+=" " ...

  5. 小程序订阅消息 订阅消息开发

    微信小程序交流QQ群:  173683895    173683866     526474645 . 群内打广告或者脏话一律飞机票 订阅消息 当用户勾选了订阅面板中的"总是保持以上选择,不 ...

  6. mqtt session保持 订阅消息_MQTT系列 | MQTT消息的发布和订阅

    1. MQTT的发布 MQTT发布中最重要的是PUBLISH数据包,PUBLISH数据包是用于sender和receiver之间传输消息数据的.当Publisher要向某个Topic发布一条消息的时候 ...

  7. boost bind使用指南

    bind - boost 头文件: boost/bind.hpp bind 是一组重载的函数模板. 用来向一个函数(或函数对象)绑定某些参数. bind的返回值是一个函数对象. 它的源文件太长了. 看 ...

  8. 微信小程序的模板消息与小程序订阅消息

    小程序订阅消息功能介绍消息能力是小程序能力中的重要组成,我们为开发者提供了订阅消息能力,以便实现服务的闭环和更优的体验. 订阅消息推送位置:服务通知订阅消息下发条件:用户自主订阅订阅消息卡片跳转能力: ...

  9. 微信小程序之订阅消息推送

    目录 1.开通订阅消息 2.请求用户授权 2.1.wx.requestSubscribeMessage(Object object) 2.2.wx.requestSubscribeDeviceMess ...

最新文章

  1. 世界五百强世硕科技工作经历——05
  2. GBDT算法原理及附有源码实现的 转
  3. Boost:ping的测试程序
  4. ITK:生成具有正确面积的结构元素
  5. ES6之Module的语法(1)
  6. python牛顿法寻找极值_python使用梯度下降和牛顿法寻找Rosenbrock函数最小值实例...
  7. 【CF 543D】Road Improvement,树形DP
  8. (24)System Verilog设计十进制计数器
  9. B站举办2021年度百大UP主盛典 科技知识类UP主占比翻倍
  10. 强大的SqlCacheDependency【转】
  11. python之requests模块
  12. HTTP性能测试工具siege
  13. ASP.NET Core 2.1 开发跨平台应用教程
  14. vb.net html图片,手把手教你VB.NET DataGrid图片显示
  15. 二进制转换八进制图解_一文帮你详细图解二进制、八进制、十进制、十六进制之间的转换...
  16. 为什么我不建议你去外包公司?
  17. Git服务器搭建及仓库克隆
  18. 海外apk转换aab 十步流程
  19. usnews美国大学计算机科学排名,最新!2019年USNews美国大学计算机专业排名
  20. 安装Debian lenny教程

热门文章

  1. 字符串类型日期时间转换为Date类型解析转换异常java.text.ParseException: Unparseable date: “2019-09-27T18:31:31+08:00”
  2. 机械+固态双硬盘时机械硬盘卡顿问题解决
  3. 为什么会出现“无法连接服务器-与网络有关或与实例有关的错误”?
  4. access性别字段_12、ACCESS数据表的筛选(ACCESS图解操作系列)
  5. 全向轮机器人左下轮运动学分析
  6. 两轮差速机器人坐标系及运动轨迹描述
  7. 四川省盐业学校九五计算机,2020年四川省盐业学校招生录取分数线
  8. c# 网口相机可以通过_双网口硬盘录像机怎么设置?录像机连接GB28181公安专网步骤指导...
  9. L1-026 I Love GPLT
  10. 洛谷——P2084 进制转换