std::bind 函数
C++11 引入了新的标准库函数 bind,std::bind 函数定义在头文件 functional 中,是一个函数模板,它就像一个函数适配器,接受一个可调用对象(callable object),生成一个新的可调用对象来“适应”原对象的参数列表。
std::bind 将可调用对象与其参数一起进行绑定,绑定后的结果可以使用 std::function 保存。std::bind 主要有以下两个作用:
- 将可调用对象和其参数绑定成一个防函数;
- 只绑定部分参数,减少可调用对象传入的参数。
std::bind 函数有两种函数原型,定义如下:
template <class F, class... Args>
/* unspecified */ bind (Fn&& f, Args&&... args);
template <class Ret, class F, class... Args>
/* unspecified */ bind (Fn&& f, Args&&... args);
参数说明:
- f:一个可调用对象(可以是函数对象、函数指针、函数引用、成员函数指针、数据成员指针),它的参数将被绑定到 args 上。
- args:绑定参数列表,参数会被值或占位符(std::placeholders)替换,其长度必须与 f 接收的参数个数一致。
std::bind绑定普通函数
double my_divide (double x, double y) {return x/y;}
auto fn_half = std::bind (my_divide,_1,2);
std::cout << fn_half(10) << '\n'; // 5
- bind 的第一个参数是函数名,普通函数做实参时,会隐式转换成函数指针。因此
std::bind (my_divide,_1,2)
等价于std::bind (&my_divide,_1,2);
- _1表示占位符,位于 中:
std::placeholders::_1;
std::bind绑定一个成员函数
struct Foo {
void print_sum(int n1, int n2)
{
std::cout << n1+n2 << '\n';
}
int data = 10;
};
int main()
{
Foo foo;
auto f = std::bind(&Foo::print_sum, &foo, 95, std::placeholders::_1);
f(5); // 100
}
- bind 绑定类成员函数时,第一个参数表示对象的成员函数的指针,第二个参数表示对象的地址。
- 必须显示的指定 &Foo::print_sum,因为编译器不会将对象的成员函数隐式转换成函数指针,所以必须在 Foo::print_sum 前添加 &;
- 使用对象成员函数的指针时,必须要知道该指针属于哪个对象,因此第二个参数为对象的地址 &foo;
std :: function 类模板
类模板 std :: function 是一个通用的多态函数包装器。 std :: function 的实例可以存储,复制和调用任何可调用的目标 :包括函数,lambda 表达式,绑定表达式或其他函数对象,以及指向成员函数和指向数据成员的指针。当 std::function 对象未包裹任何实际的可调用元素,调用该 std::function 对象将抛出 std::bad_function_call 异常。
原型如下:
template< class R, class... Args >
class function<R(Args...)>;
例如:std::function<int(int,int)> func;
则 function 类的实例 func 可以指向返回值为 int 型,有两个形参都为 int 型的函数。
#include <functional>
#include <iostream>
int f(int a, int b)
{
return a+b;
}
int main()
{
std::function<int(int, int)>func = f;
cout<<f(1, 2)<<endl; // 3
system("pause");
return 0;
}
我们再来先来看看以前 C 和 C++98 的用法:
#include<iostream>
using namespace std;
// c type global function
int c_func(int a, int b)
{
return a + b;
}
// function object
struct functor
{
public:
int operator() (int a, int b)
{
return a + b;
}
};
int main()
{
typedef int (*Func)(int ,int);
Func func = c_func;
cout<< func(1,2)<<endl; // 3
functor ft;
cout<<ft(1,2)<<endl; //3
return 0;
}
从上面我们可以看出,使用 C++11 的 function 类调用函数方便多了。
参考链接:C++11 新特性总结