总结:
只有bind保持了形式不变
翻译:调用成员函数(3)
我们决定使用指针后,有另外一个问题,即指针的生命周期控制。我们必须手动释放p_statuses中的元素,这很容易出错而且没有必要。因此,我们可能选择使用智能指针(smart pointers),代码变化如下:
std::vector<BOOST::SHARED_PTR<STATUS> > s_statuses;
s_statuses.push_back(
boost::shared_ptr<STATUS>(new status(status 1)));
s_statuses.push_back(
boost::shared_ptr<STATUS>(new status(status 2)));
s_statuses.push_back(
boost::shared_ptr<STATUS>(new status(status 3)));
s_statuses.push_back(
boost::shared_ptr<STATUS>(new status(status 4)));
s_statuses ->break_it();
s_statuses ->break_it();</STATUS></STATUS></STATUS></STATUS></BOOST::SHARED_PTR<STATUS>
现在,我们该使用标准库中的哪个适配器了?由于智能指针并没有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 <IOSTREAM>
#include <STRING>
#include <VECTOR>
#include
#include <BOOST bind.hpp="">
#include <BOOST shared_ptr.hpp="">
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<STATUS> > v_spstatus;
v_spstatus.push_back(boost::shared_ptr<STATUS>(new Status(status 1)));
v_spstatus.push_back(boost::shared_ptr<STATUS>(new Status(status 2)));
v_spstatus.push_back(boost::shared_ptr<STATUS>(new Status(status 3)));
v_spstatus.push_back(boost::shared_ptr<STATUS>(new Status(status 4)));
v_spstatus ->BreakIt();
v_spstatus ->BreakIt();
//std::cout 《 use or: 《 std::endl;
//for (std::vector<STATUS*>::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));
}</STATUS*></STATUS></STATUS></STATUS></STATUS></STATUS></BOOST>
</BOOST></ALGORITHM></VECTOR></STRING></IOSTREAM>
总结:
1、标准库中的方法不再能够使用
2、使用share_ptr必须引入头文件#include
这些例子展示了一些Boost.Bind最基本最常用的情况,也是它最擅长的方面。尽管标准库也提供了一些基本工具让我们完成同样的任务,但我们看到Bind提供了语法一致性和一些标准库目前没有的扩展功能。