boost:bind原理

废话不多说,贴上代码,简单拙劣模仿。

 

一、指向函数的指针

语法:数据类型 (*函数指针名)(形参表);

 

二、获取并调用类的成员方法

 

三、模板化

 

四、泛化

参考Boost::Any的实现,把类的成员方法和对象保存起来。

 

 

<think>我们正在讨论Boost库中bind函数的一个弃用警告,特别是关于占位符(placeholders)在全局命名空间的问题。 在较新版本的Boost(如1.73以上)中,Boost.Bind库已经弃用了在全局命名空间中定义占位符(如_1, _2等)的做法,转而要求使用命名空间boost::placeholders。 用户遇到的问题可能是:在代码中使用了_1, _2等占位符,但没有使用命名空间限定,导致编译器给出类似如下的警告: warning:boost::arg<I>& boost::operator+(boost::arg<I>, J) [with I = _1; J = int]’ is deprecated: The practice of declaring the Bind placeholders (_1, _2, ...) in the global namespace is deprecated. Please use <boost/bind/bind.hpp> + using namespace boost::placeholders, or define BOOST_BIND_GLOBAL_PLACEHOLDERS to retain the current behavior. 解决方案有两种: 1. 在代码中使用boost::placeholders命名空间,即明确使用boost::placeholders::_1, boost::placeholders::_2等,或者使用using namespace boost::placeholders; 2. 定义宏BOOST_BIND_GLOBAL_PLACEHOLDERS,保留旧行为(将占位符放在全局命名空间)。 但是,根据Boost官方文档,第一种方法是推荐的,因为第二种方法只是为了向后兼容,未来可能会被移除。 具体操作: 方法一(推荐): 在包含<boost/bind.hpp>之前,先包含<boost/bind/bind.hpp>,然后使用命名空间boost::placeholders。 例如: #include <boost/bind/bind.hpp> using namespace boost::placeholders; // 引入_1, _2等占位符 注意:有些代码可能只包含了<boost/bind.hpp>,而<boost/bind.hpp>会包含<boost/bind/bind.hpp>并自动定义BOOST_BIND_GLOBAL_PLACEHOLDERS(即保持旧行为)。但为了消除警告,我们应该直接包含<boost/bind/bind.hpp>并显式使用命名空间。 方法二(兼容): 在包含任何Boost头文件之前,定义宏BOOST_BIND_GLOBAL_PLACEHOLDERS。 例如: #define BOOST_BIND_GLOBAL_PLACEHOLDERS #include <boost/bind.hpp> 这样,占位符就会像以前一样定义在全局命名空间。 另外,如果用户使用的是较新版本的Boost(>=1.73),并且代码中已经使用了boost::placeholders,那么应该不会出现警告。 如果用户使用的是muduo网络库,它可能在其代码中使用了boost::bind。如果muduo库本身没有更新以处理这个弃用问题,那么用户可能需要在自己的代码中采用上述方法之一。 但是,注意:如果用户在自己的代码中使用了boost::bind,那么应该按照上述方法修改自己的代码。如果警告来自muduo库内部,那么可能需要修改muduo的代码(但通常我们不建议修改第三方库,除非自己维护fork)。另一种方法是定义BOOST_BIND_GLOBAL_PLACEHOLDERS宏,这样也会影响muduo内部的boost::bind使用。 因此,建议用户在自己的代码中采用方法一,并在编译自己的代码时定义宏BOOST_BIND_GLOBAL_PLACEHOLDERS(如果muduo库还没有适配)以避免muduo内部的警告。但是,如果muduo已经修复了这个问题(比如较新版本的muduo),那么就不需要了。 实际上,muduo的维护者已经注意到了这个问题,并在一些提交中进行了修复。例如,在muduo的代码中,他们可能会在包含boost/bind.hpp之前定义BOOST_BIND_GLOBAL_PLACEHOLDERS。所以,如果用户使用的是最新版的muduo,可能不会遇到这个警告。但如果用户遇到了,可以尝试在自己的编译环境中定义这个宏。 如何定义宏? 在编译命令中加入 -DBOOST_BIND_GLOBAL_PLACEHOLDERS 即可。 例如: g++ -DBOOST_BIND_GLOBAL_PLACEHOLDERS ... 或者在代码中(在包含boost头文件之前)定义。 总结步骤: 1. 如果用户在自己的代码中使用了boost::bind,并且使用了占位符(_1, _2等),则应该: 方法一(推荐): 修改代码,在包含boost/bind相关头文件的地方,改为: #include <boost/bind/bind.hpp> using namespace boost::placeholders; 方法二(临时): #define BOOST_BIND_GLOBAL_PLACEHOLDERS #include <boost/bind.hpp> 2. 如果警告来自muduo库内部,那么可以在编译整个项目时定义宏BOOST_BIND_GLOBAL_PLACEHOLDERS(通过编译选项-D),或者等待muduo库更新。 注意:由于muduo库可能已经在其头文件中包含了boost/bind.hpp,所以用户需要在包含muduo头文件之前定义宏BOOST_BIND_GLOBAL_PLACEHOLDERS,这通常很难做到(因为muduo头文件可能被间接包含)。因此,更可靠的方法是在编译命令中定义该宏。 例如,在CMakeLists.txt中添加: add_definitions(-DBOOST_BIND_GLOBAL_PLACEHOLDERS) 或者,如果使用make,在Makefile的CFLAGS/CXXFLAGS中添加。 但是,请注意,定义这个宏可能会在自己的代码中重新启用全局占位符,这与我们在自己代码中使用命名空间的做法并不冲突。所以,可以同时采用:在自己代码中使用命名空间,同时定义宏以消除第三方库的警告。 然而,更推荐的做法是更新muduo到已经修复此问题的版本(如果存在)。根据muduo的GitHub仓库,这个问题在2019年10月左右就已经有修复(例如,在muduo的CMakeLists.txt中定义这个宏)。 因此,检查muduo的版本和编译选项可能是第一步。 如果用户不想更新muduo,那么就在自己的编译选项中定义宏。 最后,关于muduo的编译,用户之前的问题是关于编译示例时找不到Makefile,我们已经解决了。现在这个问题是关于Boost bind的弃用警告,所以我们应该专注于解决这个警告。 总结:根据用户的具体情况,选择修改自己的代码和/或定义宏。</think>### 解决 Boost Bind 弃用警告:占位符全局命名空间问题 在编译使用 Boost 和 muduo 的 C++ 项目时,遇到 `boost::bind` 的弃用警告通常是因为较新版本的 Boost(1.73+)改变了占位符的命名空间规则。以下是完整解决方案: --- #### 问题原因 Boost 1.73+ 默认要求**显式使用占位符命名空间**,弃用了全局命名空间的 `_1, _2` 等占位符: ```cpp // 旧用法 (触发警告) boost::bind(callback, _1, 123); // 新用法 (正确) boost::bind(callback, boost::placeholders::_1, 123); ``` [^1] --- #### 解决方案 ##### 方法1:显式声明命名空间(推荐) 在代码顶部添加命名空间声明: ```cpp #include <boost/bind/bind.hpp> // 添加以下声明 using namespace boost::placeholders; // 允许使用 _1, _2 等简写 // 使用示例 boost::bind(&MyClass::handler, this, _1, _2); ``` ##### 方法2:全局兼容模式(临时方案) 在编译时定义宏(不推荐长期使用): ```bash # CMakeLists.txt 中添加 add_definitions(-DBOOST_BIND_GLOBAL_PLACEHOLDERS) # 或 g++ 编译时添加 g++ -DBOOST_BIND_GLOBAL_PLACEHOLDERS ... ``` ##### 方法3:完整限定占位符(最安全) ```cpp boost::bind(&MyClass::handler, this, boost::placeholders::_1, boost::placeholders::_2); ``` --- #### muduo 项目特殊处理 如果警告来自 muduo 源码: 1. 更新 muduo 到最新版(已修复此问题): ```bash git pull origin master ``` 2. 或手动修改 muduo 代码: ```cpp // 在 muduo 源码中搜索 #include <boost/bind.hpp> // 在下方添加: using namespace boost::placeholders; ``` --- #### 验证修复 重新编译后检查警告是否消失: ```bash make clean make VERBOSE=1 # 显示详细编译命令 ``` 观察输出中是否还有 `deprecated-declarations` 相关警告。 --- #### 原理说明 - Boost 1.73+ 将占位符移入 `boost::placeholders` 命名空间[^1] - 旧全局命名空间用法会导致编译警告 - `BOOST_BIND_GLOBAL_PLACEHOLDERS` 是向后兼容的临时方案 - muduo 在 2020 年后已修复此问题(commit 6d4b4c5) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值