//-------------- Boost.Bind --------------
#include <vcl.h>
#include <vector>
#include <iostream>
#include <algorithm>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#pragma hdrstop
//----------------------------------------
#pragma argsused
using namespace std;
void print_sum(int a, int b)
{
cout << (a + b) << endl;
}
class Person
{
public:
string name;
int age;
Person(const string& str, int i):name(str), age(i)
{
}
void PrintInformation(void)
{
cout<< "Name = " << name << "; " << "Age = " << age << endl;
}
};
int main(int argc, char* argv[])
{
// 例子1:
// 三者都相当于调用了函数 print_sum(50, 100)
boost::bind(&print_sum, 50, 100)(); // (1)
boost::bind(&print_sum, _1, 100)(50); // (2)
boost::bind(&print_sum, _1, _2)(50, 100); // (3)
// 四者都相当于调用了函数 print_sun(100, 50)
boost::bind(&print_sum, 100, 50)(); // (4)
boost::bind(&print_sum, 100, _1)(50); // (5)
boost::bind(&print_sum, _1, 50)(100); // (6)
boost::bind(&print_sum, _2, _1)(50, 100); // (7)
int array[4] = {11, 22, 33, 44};
for_each(array, array + 4, boost::bind(&print_sum, _1, 100)); // (8)
// 例子2:元素是以值的方式存储的, 所以需要适配器men_fun_ref
vector<Person> v2;
v2.push_back(Person(string("person 1"), 25));
v2.push_back(Person(string("person 2"), 24));
v2.push_back(Person(string("person 3"), 23));
v2.push_back(Person(string("person 4"), 22));
// 三者完成的任务相同
// 由于多次调用v2.end()使效率降低、代码冗长
for(vector<Person>::iterator i = v2.begin(); i != v2.end(); ++i)
{
i->PrintInformation();
}
// 需要适配器men_fun_ref来对v2的元素成员调用成员函数
for_each(v2.begin(), v2.end(),mem_fun_ref(Person::PrintInformation));
// 简洁、清楚表达意图
for_each(v2.begin(), v2.end(), bind(Person::PrintInformation, _1));
// 例子3:元素是以指针方式存储的, 需要适配器men_fun, 且需要显式的删除元素
vector<Person*> v3;
v3.push_back(new Person(string("person 1"), 25));
v3.push_back(new Person(string("person 2"), 24));
v3.push_back(new Person(string("person 3"), 23));
v3.push_back(new Person(string("person 4"), 22));
// 三者完成的任务相同
// 多次调用v3.end()使效率降低、代码冗长
for(vector<Person*>::iterator i = v3.begin(); i != v3.end(); ++i)
{
(*i)->PrintInformation();
}
// 需要适配器men_fun来对v3的元素成员调用成员函数
for_each(v3.begin(), v3.end(), mem_fun(Person::PrintInformation));
// 简洁、清楚表达意图
for_each(v3.begin(), v3.end(), bind(Person::PrintInformation, _1));
// 显式的删除v3元素, 增加了代码量
for(vector<Person*>::iterator i = v3.begin(); i != v3.end(); ++i)
{
delete (*i);
}
// 例子4:
vector<boost::shared_ptr<Person> > v4;
v4.push_back(boost::shared_ptr<Person>(new Person("person 1", 25)));
v4.push_back(boost::shared_ptr<Person>(new Person("person 1", 24)));
v4.push_back(boost::shared_ptr<Person>(new Person("person 1", 23)));
v4.push_back(boost::shared_ptr<Person>(new Person("person 1", 22)));
// 两者完成的任务相同
// 多次调用v4.end()使效率降低、即使不需要手动删除元素代码依然冗长
for(vector<boost::shared_ptr<Person> >::iterator i = v4.begin(); i != v4.end(); ++i)
{
(*i)->PrintInformation();
}
// 因为智能指针没有成员函数 适配器men_fun_ref和men_fun都不再适用
// 然而boost::bind仍可以简洁、清楚的表达意图
for_each(v4.begin(), v4.end(), bind(Person::PrintInformation, _1));
system("PAUSE");
return 0;
}
//-------------------------------
小结:不论采用的是值语义还是指针语义,用于绑定的语法是相同的,甚至在使用智能指针时也是相同的。有时候,使用不同的语法有助于代码的理解,然而这里情况就不同了——这里的任务只是对容器中的元素调用成员函数。但不应该低估语法一致性的价值,它对于编写代码的人和日后维护代码(假定需要维护)的人,都是有帮助的。尽管标准库也提供了一些完成相同工作的基本工具,但我们看到boost.bind不仅提供了一致的语法,而且也增加了标准库目前所缺少的功能。