網站首頁 編程語言 正文
1. boost::bind
boost::bind
是標準庫函數std::bind1st
和std::bind2nd
的一種泛化形式。其可以支持函數對象、函數、函數指針、成員函數指針,并且綁定任意參數到某個指定值上或者將輸入參數傳入任意位置。
1.1 通過functions和function pointers使用bind
給定如下函數:
int f(int a, int b) { return a + b; } int g(int a, int b, int c) { return a + b + c; }
- 可以綁定所有參數,如:
bind(f, 1, 2)等價于f(1, 2); bind(g, 1, 2, 3)等價于g(1, 2, 3);
- 也可以選擇性地綁定參數,如:
bind(f, _1, 5)(x)等價于f(x, 5),其中_1是一個占位符,表示用第一個參數來替換;
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函數的參數一般為變量的copy,如:
int i = 5; bind(f, i, _1);
比如:
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就無法生成并報錯。
如果想傳入變量的引用,可以使用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擁有的是函數對象的副本,但是也可以使用boost::ref和boost::cref來傳入函數對象的引用,尤其是當該function object是non-copyable或者expensive to copy。
1.3 通過pointers to members使用bind
bind將傳入的成員(數據成員和成員函數)指針作為第一個參數,其行為如同使用boost::mem_fn將成員指針轉換為一個函數對象,即:
bind(&X::f, args);
等價于bind<R>(mem_fn(&X::f), args)
,其中R為X::f的返回類型(成員函數)或類型(數據成員)。
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 分別為第一個和第二個輸入參數。
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); }
參考資料
boost::bind()詳解
ROS與boost:bind()簡單解析
原文鏈接:https://blog.csdn.net/lemonxiaoxiao/article/details/128613919
相關推薦
- 2022-08-13 Redis 性能影響 - 內存碎片和緩沖區
- 2022-12-15 C++?Boost?Thread線程使用示例詳解_C 語言
- 2022-10-16 Qt實現進程間通信_C 語言
- 2022-06-25 iOS實現文件下載功能_IOS
- 2023-05-13 Python?readline()和readlines()函數實現按行讀取文件_python
- 2022-09-04 centos搭建部署docker環境的詳細步驟_docker
- 2022-08-11 boost.asio框架系列之調度器io_service_C 語言
- 2023-12-08 maven中mybatis-generator插件執行報錯:Cannot resolve class
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支