在《超越C++标准库-Boost库导论》一书的第九章中,介绍了Bind库的使用,文中用简短的代码来演示了Bind库是如何工作的,其中涉及到若干知识点。
1、先说明一下Boost.Bind库是如何使用的:
struct MyStruct
{
int a;
float b;
string str;
void ShowMsg()
{
cout<<"who am i?"<<endl;
}
};
vector<MyStruct*> vec2;
vec2.push_back(new MyStruct());
vec2.push_back(new MyStruct());
for_each(vec2.begin(), vec2.end(), boost::bind(&MyStruct::ShowMsg, _1)); //调用vecotr中每个元素的ShowMsg函数
2、绑定(精简的)的实现代码如下:
namespace
{
class placeholder {};
placeholder _1;
}
以上代码在匿名命名空间中定义占位符类 placeholder 以及其实例 _1,匿名命名空间中的对象和具有static类型的文件型变量类似,只能在当前文件中被使用。
template <typename R, typename T, typename Arg>
class simple_bind_t
{
typedef R (T::*fn)(Arg);
public:
simple_bind_t(fn f, const T& t) : fn_(f), t_(t){}
R operator()(Arg& a){return (t_.*fn_)(a);}
private:
fn fn_;
T t_;
};
以上代码定义了一个函数对象类模板 imple_bind_t,3个模板参数R,T,Arg分别为返回值类型,类类型以及参数类型。类中定义了两个数据成员:
fn fn_; //fn_ 为一个函数指针变量,指向类T的一个成员函数,该成员函数返回值为R,参数为Arg;
T t_; //由于调用类的非静态成员函数,需要T类型的类对象t_。
重载操作符 operator() 通过 t_ 与 fn_ 以a为参数调用了类T的成员函数。
template <typename R, typename T, typename Arg>
simple_bind_t<R, T, Arg> simple_bind(R(T::*fn)(Arg), const T& t, const placeholder&)
{
return simple_bind_t<R, T, Arg>(fn, t);
}
以上代码实现绑定,如果理解了类模板中的代码,这个也就很好理解了,就是构造一个simple_bind_t<R, T, Arg>对象,并返回。
class Test
{
public:
void do_stuff(const std::vector<int>& v)
{
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
}
};
Test t;
vector<int> vec6;
vec6.push_back(42);
vec6.push_back(52);
simple_bind(&Test::do_stuff, t, _1)(vec6);
以上代码演示了绑定的使用,其中Test::do_stuff为成员函数,t为类的实例, _1 为占位符(没有使用),vec6 为成员函数的参数。运行后,输出vector中的每一个元素。