std::for_each( p_statuses.begin(), p_statuses.end(), boost::bind(&status::report,_1));
如你所见,这与之前非指针元素的代码没有任何区别。也就是说如果你理解了刚才的bind,那么这个也能理解。
原创:编程实验
#include
#include
#include
#include
#include
class Status { public: Status(const std::string &name) : name_(name), ok_(true){} void BreakIt() { ok_ = false; } bool IsBroken() const { return ok_; } void Report() const { std::cout << name_ << is << (ok_ ok : broken) << std::endl; } private: std::string name_; bool ok_; }; int main() { std::vector
v_pstatus; v_pstatus.push_back(new Status(status 1)); v_pstatus.push_back(new Status(status 2)); v_pstatus.push_back(new Status(status 3)); v_pstatus.push_back(new Status(status 4)); v_pstatus[1]->BreakIt(); v_pstatus[2]->BreakIt(); std::cout << use or: << std::endl; for (std::vector
::iterator it = v_pstatus.begin(); it < v_pstatus.end(); it++) { (*it)->Report(); } std::cout << use or_each, mem_fun_ref: << std::endl; std::for_each(v_pstatus.begin(), v_pstatus.end(), std::mem_fun(&Status::Report)); std::cout << use or_each, bind: << std::endl; std::for_each(v_pstatus.begin(), v_pstatus.end(), boost::bind(&Status::Report, _1)); }
总结:
只有bind保持了形式不变
翻译:调用成员函数(3)
我们决定使用指针后,有另外一个问题,即指针的生命周期控制。我们必须手动释放p_statuses中的元素,这很容易出错而且没有必要。因此,我们可能选择使用智能指针(smart pointers),代码变化如下:
std::vector
> s_statuses;
s_statuses.push_back(
boost::shared_ptr
(new status(status 1))); s_statuses.push_back( boost::shared_ptr
(new status(status 2))); s_statuses.push_back( boost::shared_ptr
(new status(status 3))); s_statuses.push_back( boost::shared_ptr
(new status(status 4))); s_statuses[1]->break_it(); s_statuses[2]->break_it();
现在,我们该使用标准库中的哪个适配器了?由于智能指针并没有report成员函数,mem_fun和mem_fun_ref都不能用了。如下代码会编译失败。
std::for_each( s_statuses.begin(), s_statuses.end(), std::mem_fun(&status::report));
我们的好运用完了,标准库并不能帮我们完成这个任务。因此,我们只能借助于之前想避开的for形式或者……Boost.Bind,它可以完全正确地完成任务。
std::for_each( s_statuses.begin(), s_statuses.end(), boost::bind(&status::report,_1));
这与前面的代码是完全一样的(除了容器的名字)。同样的语法可以用于绑定值语义、指针语义或者只能指针。有时候,不同的语法可以帮助我们理解代码,但在我们讨论的情况中不是这样——我们手中的任务是在容器的元素上调用成员函数,没有其他的需求。语法一致的价值是不容轻视的,它既帮助了写代码的人,也帮助了以后维护代码的人。(当然,实际上我们没有写需要维护的代码,但出于参数的考虑,让我们假装是这样做的吧^_^)。
原创:编程实验
#include
#include
#include
#include
#include
#include
class Status { public: Status(const std::string &name) : name_(name), ok_(true){} void BreakIt() { ok_ = false; } bool IsBroken() const { return ok_; } void Report() const { std::cout << name_ << is << (ok_ ok : broken) << std::endl; } private: std::string name_; bool ok_; }; int main() { std::vector< boost::shared_ptr
> v_spstatus; v_spstatus.push_back(boost::shared_ptr
(new Status(status 1))); v_spstatus.push_back(boost::shared_ptr
(new Status(status 2))); v_spstatus.push_back(boost::shared_ptr
(new Status(status 3))); v_spstatus.push_back(boost::shared_ptr
(new Status(status 4))); v_spstatus[1]->BreakIt(); v_spstatus[2]->BreakIt(); //std::cout << use or: << std::endl; //for (std::vector
::iterator it = v_spstatus.begin(); it < v_spstatus.end(); it++) //{ // (*it)->Report(); //} //std::cout << use or_each, mem_fun_ref: << std::endl; //std::for_each(v_spstatus.begin(), v_spstatus.end(), std::mem_fun(&Status::Report)); std::cout << use or_each, bind: << std::endl; std::for_each(v_spstatus.begin(), v_spstatus.end(), boost::bind(&Status::Report, _1)); }
总结:
1、标准库中的方法不再能够使用
2、使用share_ptr必须引入头文件#include
这些例子展示了一些Boost.Bind最基本最常用的情况,也是它最擅长的方面。尽管标准库也提供了一些基本工具让我们完成同样的任务,但我们看到Bind提供了语法一致性和一些标准库目前没有的扩展功能。