一 Boost::bind
在STL中,我们经常需要使用bind1st,bind2st函数绑定器和fun_ptr,mem_fun等函数适配器,这些函数绑定器和函数适配器使用起来比较麻烦,需要根据是全局函数还是类的成员函数,是一个参数还是多个参数等做出不同的选择,而且有些情况使用STL提供的不能满足要求,所以如果可以我们最好使用boost提供的bind,它提供了统一的接口,提供了更多的支持,比如说它增加了shared_ptr,虚函数,类成员的绑定。
二 源码剖析
1) bind1st,bind2st函数绑定器,把二元函数对象变为一元函数对象。
2) mem_fun,把成员函数变为函数对象。
3) fun_ptr,把一般的全局函数变为函数对象。
4) boost::bind(),包含了以上所有的功能。
三 实例
1)区别与mem_fun和fun_ptr
#include <functional>
#include <iostream>
#include <string>
#include "boost/bind.hpp"
class some_class


{
public:
void print_string(const std::string& s) const

{
std::cout << s << '\n';
}
void print_classname()

{
std::cout << "some_class" << std::endl;
}
};
void print_string(const std::string s)


{ std::cout << s << '\n';
}
void print_functionname()


{
std::cout << "Print_functionname" <<std::endl;
}
int main()


{
std::ptr_fun(&print_string)("hello1");
//std::ptr_fun<void>(&print_functionname);
some_class sc0;
std::mem_fun_ref(&some_class::print_classname)(sc0);
std::mem_fun_ref<void,some_class>(&some_class::print_classname)(sc0);
//std::mem_fun1_ref<void,some_class,const std::stirng>(&some_class::print_string)(sc0,"hello2");

(boost::bind(&print_string,_1))("Hello func!");
boost::bind(&print_functionname);
some_class sc;
(boost::bind(&some_class::print_classname,_1)(sc));
(boost::bind(&some_class::print_string,_1,_2))(sc,"Hello member!");
}
2)区别与bind1st和bind2st
#include <functional>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include "boost/bind.hpp"
void main()


{
std::vector<int> ints;
ints.push_back(7);
ints.push_back(4);
ints.push_back(12);
ints.push_back(10);
int count=std::count_if(ints.begin(),
ints.end(),
boost::bind(std::logical_and<bool>(),boost::bind(std::greater<int>(),_1,5),boost::bind(std::less_equal<int>(),_1,10))
);
std::cout << count << '\n';
std::vector<int>::iterator int_it=std::find_if(ints.begin(),
ints.end(),
boost::bind(std::logical_and<bool>(),boost::bind(std::greater<int>(),_1,5),boost::bind(std::less_equal<int>(),_1,10))
);
if (int_it!=ints.end())

{ std::cout << *int_it << '\n';}

}
3)区别传ref和传instance
// bind instance or reference
#include <functional>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include "boost/bind.hpp"
class tracer


{
public:

tracer()
{ std::cout << "tracer::tracer()\n"; }

tracer(const tracer& other)
{ std::cout << "tracer::tracer(const tracer& other)\n"; }
tracer& operator=(const tracer& other)

{ std::cout << "tracer& tracer::operator=(const tracer& other)\n"; return *this; }

~tracer()
{ std::cout << "tracer::~tracer()\n";
}
void print(const std::string& s) const

{ std::cout << s << '\n'; }
};

void main()


{
tracer t;
boost::bind(&tracer::print,t,_1)(std::string("I'm called on a copy of t\n"));
tracer t1;
boost::bind(&tracer::print,boost::ref(t1),_1)( std::string("I'm called directly on t\n"));

}
4)绑定虚函数
//bind vitual class function
#include <functional>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include "boost/bind.hpp"

class base
{
public:
virtual void print() const

{ std::cout << "I am base.\n";
}

virtual ~base()
{}
};
class derived : public base


{
public:
void print()const

{ std::cout << "I am derived.\n"; }
};

void main()


{
derived d;
base b;
boost::bind(&base::print,_1)(b);
boost::bind(&base::print,_1)(d);
}
5)绑定成员变量
// bind class's member
#include <functional>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include "boost/bind.hpp"
class personal_info


{
std::string name_;
std::string surname_;
unsigned int age_;
public:

personal_info(const std::string& n,const std::string& s,unsigned int age):name_(n),surname_(s),age_(age)
{}

std::string name() const
{return name_;}

std::string surname() const
{return surname_;}

unsigned int age() const
{return age_;}
};

void main()


{
std::vector<personal_info> vec;
vec.push_back(personal_info("Little","John",30));
vec.push_back(personal_info("Friar", "Tuck",50));
vec.push_back(personal_info("Robin", "Hood",40));
std::sort(vec.begin(),
vec.end(),
boost::bind(std::less<unsigned int>(),boost::bind(&personal_info::age,_1),boost::bind(&personal_info::age,_2))
);
std::sort(vec.begin(),
vec.end(),
boost::bind(std::less<std::string>(),boost::bind(&personal_info::surname,_1),boost::bind(&personal_info::surname,_2))
);
}
四 注意
1) 现在的类库最多可以支持9个参数。
2)在绑定一个成员函数时,bind 表达式的第一个参数必须是成员函数所在类的实例!理解这个规则的最容易的方法是,这个显式的参数将取替隐式的 this ,被传递给所有的非静态成员函数。细心的读者将会留意到,实际上这意味着对于成员函数的绑定器来说,只能支持八个参数,因为第一个要用于传递实际的对象。
3)当我们传递某种类型的实例给一个 bind 表达式时,它将被复制,除非我们显式地告诉 bind 不要复制它。要避免复制,我们必须告诉bind 我们想传递引用而不是它所假定的传值。我们要用 boost::ref 和 boost::cref (分别用于引用和 const 引用)来做到这一点,它们也是Boost.Bind 库的一部分。还有一种避免复制的方法;就是通过指针来传递参数而不是通过值来传递。
4) 通过 Boost.Bind, 你可以象使用非虚拟函数一样使用虚拟函数,即把它绑定到最先声明该成员函数为虚拟的基类的那个虚拟函数上。这个绑定器就可以用于所有的派生类。如果你绑定到其它派生类,你就限制了可以使用这个绑定器的类。
5)bind还可以绑定成员变量。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具