C++?ROS與boost:bind()使用詳解
1. boost::bind
boost::bind
是標準庫函數(shù)std::bind1st
和std::bind2nd
的一種泛化形式。其可以支持函數(shù)對象、函數(shù)、函數(shù)指針、成員函數(shù)指針,并且綁定任意參數(shù)到某個指定值上或者將輸入?yún)?shù)傳入任意位置。
1.1 通過functions和function pointers使用bind
給定如下函數(shù):
int f(int a, int b) { return a + b; } int g(int a, int b, int c) { return a + b + c; }
- 可以綁定所有參數(shù),如:
bind(f, 1, 2)等價于f(1, 2); bind(g, 1, 2, 3)等價于g(1, 2, 3);
- 也可以選擇性地綁定參數(shù),如:
bind(f, _1, 5)(x)等價于f(x, 5),其中_1是一個占位符,表示用第一個參數(shù)來替換;
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函數(shù)的參數(shù)一般為變量的copy,如:
int i = 5; bind(f, i, _1);
比如:
void func(int a, int b, int c); boost::bind(func, 7, _1, _2);
boost::bind()
會返回一個函數(shù)對象,所以boost::bind(func, 7, _1, _2)
得到一個函數(shù)對象ob
,即ob = boost::bind(func, 7, _1, _2)
。當我們調(diào)用ob(3,4)
時,相當于調(diào)用func(7,3,4)
,如果連著一起寫那就是boost::bind(func, 7, _1, _2)(3, 4)
;
需要注意的一點是,boost::bind()
里的參數(shù)個數(shù)一定要與被bind包括的函數(shù)的形參個數(shù)相同,否則這個bind函數(shù)對象ob就無法生成并報錯。
如果想傳入變量的引用,可以使用boost::ref
和boost::cref
,如:
int i = 5; bind(f, ref(i), _1); bind(f, cref(i), _1);
1.2 通過function objects使用bind
struct F { int operator()(int a, int b) { return a – b; } bool operator()(long a, long b) { return a == b; } }; F f; int x = 100; bind<int>(f, _1, _1)(x); // f(x, x)
可能某些編譯器不支持上述的bind語法,可以用下列方式代替:
boost::bind(boost::type<int>(), f, _1, _1)(x);
默認情況下,bind擁有的是函數(shù)對象的副本,但是也可以使用boost::ref和boost::cref來傳入函數(shù)對象的引用,尤其是當該function object是non-copyable或者expensive to copy。
1.3 通過pointers to members使用bind
bind將傳入的成員(數(shù)據(jù)成員和成員函數(shù))指針作為第一個參數(shù),其行為如同使用boost::mem_fn將成員指針轉換為一個函數(shù)對象,即:
bind(&X::f, args);
等價于bind<R>(mem_fn(&X::f), args)
,其中R為X::f的返回類型(成員函數(shù))或類型(數(shù)據(jù)成員)。
struct X { bool f(int a); }; X x; shared_ptr<X> p(new X); int i = 5; bind(&X::f, ref(x), _1)(i); // x.f(i) bind(&X::f, &x, _1)(i); // (&x)->f(i) bind(&X::f, x, _1)(i); // x.f(i) bind(&X::f, p, _1)(i); // p->f(i)
如:
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 分別為第一個和第二個輸入?yún)?shù)。
2. ROS與bind()
2.1
當我們訂閱一個消息時候,會調(diào)用一個返回函數(shù)。如:
ros::Subscriber topic_sub=n.subscribe<std_msgs::Int8>("/topic", 10, Callback);
這樣Callback函數(shù)應該包含一個參數(shù),即:
void Callback(const std_msgs::Int8::ConstPtr& msg){}
但是,如果我們想要多參數(shù)傳入的話,就需要使用boost庫中的bind函數(shù)。例如,當我們的回調(diào)函數(shù)是這樣的:
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; }
當使用①函數(shù)時:
ros::Subscriber scan_sub=n.subscribe<std_msgs::Int8>("/topic", 10, \ boost::bind(&Callback, _1, index1, index2));//①
返回函數(shù)調(diào)用的是:
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); }
當使用②函數(shù)時:
ros::Subscriber scan_sub = n.subscribe<std_msgs::Int8>("topic", 10, Callback);//②
返回函數(shù)調(diào)用的是:
void Callback(const std_msgs::Int8::ConstPtr &msg) { printf("%d \r\n", *msg); }
參考資料
到此這篇關于C++ ROS與boost:bind()詳解的文章就介紹到這了,更多相關C++ ROS與boost:bind()內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C++實現(xiàn)的一個可以寫遞歸lambda的Y函數(shù)
這篇文章主要介紹了C++實現(xiàn)的一個可以寫遞歸lambda的Y函數(shù),在Y函數(shù)的幫助,這個lambda表達是可以成功看到自己,然后遞歸調(diào)用的,需要的朋友可以參考下2014-07-07C語言利用system調(diào)用系統(tǒng)命令行詳情
這篇文章主要介紹了C語言利用system調(diào)用系統(tǒng)命令行詳情,system就是調(diào)用系統(tǒng)命令行,輸入為字符串,然后把這個字符串輸出給命令行,讓命令行執(zhí)行。下文的具體內(nèi)容,需要的小伙伴可以參考一下2022-01-01C語言報錯:Format String Vulnerability的多種解決方案
Format String Vulnerability(格式化字符串漏洞)是C語言中常見且嚴重的安全漏洞之一,它通常在程序使用不受信任的輸入作為格式化字符串時發(fā)生,本文將詳細介紹Format String Vulnerability的產(chǎn)生原因,提供多種解決方案,需要的朋友可以參考下2024-06-06