官方文档对于bind接口的概述解释:Bind function arguments
在C++11中,std::bind
是一个非常有用的工具,用于将函数、成员函数或函数对象与特定的参数绑定在一起,生成一个新的可调用对象。std::bind
可以用于部分应用函数参数、改变参数的顺序、绑定成员函数等。
#include <functional> // 需要包含这个头文件
auto new_callable = std::bind(callable, arg1, arg2, ..., argN);
-
callable
可以是函数、函数指针、成员函数指针、函数对象等。 -
arg1, arg2, ..., argN
是传递给callable
的参数。这些参数可以是具体的值,也可以是占位符std::placeholders::_1
,std::placeholders::_2
, 等等。
示例
1. 绑定普通函数
#include <iostream>
#include <functional>
void print_sum(int a, int b) {
std::cout << a + b << std::endl;
}
int main() {
auto f = std::bind(print_sum, 10, 20);
f(); // 输出 30
return 0;
}
在这个例子中,std::bind
将 print_sum
函数与参数 10
和 20
绑定在一起,生成了一个新的可调用对象 f
。调用 f()
时,相当于调用了 print_sum(10, 20)
。
2. 使用占位符
#include <iostream>
#include <functional>
void print_sum(int a, int b) {
std::cout << a + b << std::endl;
}
int main() {
using namespace std::placeholders; // 引入占位符
auto f = std::bind(print_sum, _1, _2);
f(10, 20); // 输出 30
auto g = std::bind(print_sum, _2, _1);
g(10, 20); // 输出 30,参数顺序被交换
return 0;
}
在这个例子中,_1
和 _2
是占位符,表示在调用 f
或 g
时传递的第一个和第二个参数。
3. 绑定成员函数
#include <iostream>
#include <functional>
class MyClass {
public:
void print_sum(int a, int b) {
std::cout << a + b << std::endl;
}
};
int main() {
MyClass obj;
auto f = std::bind(&MyClass::print_sum, &obj, 10, 20);
f(); // 输出 30
using namespace std::placeholders;
auto g = std::bind(&MyClass::print_sum, &obj, _1, _2);
g(10, 20); // 输出 30
return 0;
}
在这个例子中,std::bind
绑定了 MyClass
的成员函数 print_sum
,并且需要传递一个对象指针 &obj
作为第一个参数。
4. 绑定函数对象
#include <iostream>
#include <functional>
struct Add {
int operator()(int a, int b) const {
return a + b;
}
};
int main() {
Add add;
auto f = std::bind(add, 10, 20);
std::cout << f() << std::endl; // 输出 30
using namespace std::placeholders;
auto g = std::bind(add, _1, _2);
std::cout << g(10, 20) << std::endl; // 输出 30
return 0;
}
在这个例子中,std::bind
绑定了一个函数对象 add
,并生成了一个新的可调用对象 f
和 g
。
5.线程池
基于bind的作用,当我们在设计一些线程池,或者任务池的时候,就可以将将任务池中的任务设置为函数类型,函数的参数由添加任务者直接使用bind进行适配绑定设置,而任务池中的任务被处理,只需要取出一个个的函数进行执行即可。
这样做有个好处就是,这种任务池在设计的时候,不用考虑都有哪些任务处理方式了,处理函数该如何设计,有多少个什么样的参数,这些都不用考虑了,降低了代码之间的耦合度。
#include <iostream>
#include <functional>
#include <cstring>
#include <vector>
void Print(const std::string& str, int x)
{
std::cout << str << "--->" << x << std::endl;
}
int main()
{
using task_t = std::function<void()>;
std::vector<task_t> _task;
_task.push_back(std::bind(Print, "wuxu", 666));
_task.push_back(std::bind(Print, "cdd", 888));
_task.push_back(std::bind(Print, "Mudu", 666));
for(auto& f : _task)
f();
}