ROS与boost:bind()简单解析

1 boost:bind()

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

void func(x,y);

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

auto ob = boost::bind(func,a1,a2)();//ob()==func(a1,a2);
//因为bind()里没有占位符,所以ob()无参数,a1,a2作为参数直接输入func

一般来说boost::bind有两种方式的调用,一种是对自由方法,也即非类方法, 一种是对类方法.

  • 对自由方法来说,直接boost::bind(函数名, 参数1,参数2,…)
  • 对类方法来说,直接boost::bind(&类名::方法名,类实例指针,参数1,参数2)
1.1 非类方法

bind(f, _1, 5)(x)等同于f(x, 5).这里的 _1 相当于一个占位符,用来代替第一个输入参数。又如:

bind(f, 5, _1)(x);                     // f(5, x)
bind(f, _2, _1)(x, y);                 // f(y, x)
bind(g, _1, 9, _1)(x);                 // g(x, 9, x)
bind(g, _3, _3, _3)(x, y, z);          // g(z, z, z)
bind(g, _1, _1, _1)(x, y, z);          // g(x, x, x)

比如:

void func(int a, int b, int c);
boost::bind(func, 7, _1, _2);

boost::bind()会返回一个函数对象,所以boost::bind(func, 7, _1, _2)得到一个函数对象ob,即ob = boost::bind(func, 7, _1, _2).当我们调用ob(3,4)时,相当于调用func(7,3,4),如果连着一起写那就是boost::bind(func, 7, _1, _2)(3, 4);

需要注意的一点是,boost::bind()里的参数个数一定要与被bind包括的函数的形参个数相同,否则这个bind函数对象ob就无法生成并报错.

1.2 类方法

如:

cb = boost::bind(&NodeExample::configCallback, node_example, _1, _2);

其中的 node_example是指针变量NodeExample *node_example = new NodeExample();
因此boost::bind(&NodeExample::configCallback, node_example, _1, _2)的意思就是 node_example -> configCallback(x, y);

又如:

boost::bind(&MyNode::doneCb, this, _1, _2);

意思就是this -> doneCb(x, y) 这里的x,y 分别为第一个和第二个输入参数.

2 ROS与bind()
2.1

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

ros::Subscriber topic_sub=n.subscribe<std_msgs::Int8>("/topic", 10, Callback);

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

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

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

void Callback(const std_msgs::Int8::ConstPtr& msg, int& x, int& y){}
2.2 示例
#include <ros/ros.h>
#include <std_msgs/Int8.h>

int index1 = 1;
int index2 = 2;
void Callback(const std_msgs::Int8::ConstPtr &msg, int &x, int &y) {
  printf("%d", *msg);
  printf("%d \r\n", x);
  printf("%d \r\n", y);
}
void Callback(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>("/topic", 10, 
        //boost::bind(&Callback, _1, index1, index2));//①
  ros::Subscriber scan_sub = n.subscribe<std_msgs::Int8>("topic", 10, Callback);//②
  ros::Rate r(rate);
  while (n.ok()) {
    ros::spinOnce();
    r.sleep();
  }
  return 0;
}

当使用①函数时

ros::Subscriber scan_sub=n.subscribe<std_msgs::Int8>("/topic", 10, \
        boost::bind(&Callback, _1, index1, index2));//①

返回函数调用的是:

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

当使用②函数时

ros::Subscriber scan_sub = n.subscribe<std_msgs::Int8>("topic", 10, Callback);//②

返回函数调用的是:

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

ROS入门(五) C++使用boost::bind 订阅消息中的返回函数传入多个参数

boost::bind的使用

ROS与boost::bind( )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值