std::function
std::function是一个类,而且是一个模板类,它表示了一个函数类型。
// 一个函数对象,该函数返回值为void,参数列表为空
std::function funcPtr;
// 一个函数对象,返回值为int,参数列表为两个int
std::function funcPtr2;
假如我们定义了一些函数,我们可以用std::function<>函数对象来保存这些函数
int max(int x, int y)
{
if(x > y) return x;
return y;
}
std::function funcPtr = max;
// 其实调用了max,从这个例子看出,std::function<>类型,类似C语言的函数指针类型
int maxValue = funcPtr(3, 5);
printf("%d\n", maxValue);
类比C语言如下:
int max(int x, int y)
{
if(x > y) return x;
return y;
}
typedef int(*FuncType)(int, int);
FuncType funcPtr = max;
funcPtr(3, 5);
以上两个代码的效果是完全一样的。
在C++中,为什么要用std::function类来代替函数指针类型,目的是为了更好的封装,std::function和std::bind配合起来,能实现更多灵活的效果。下面就来说说std::bind
std::bind
std::bind是标准C++库中的一个函数,它的作用是将一个函数,bind成一个std::function对象。
int max(int x, int y)
{
if(x > y) return x;
return y;
}
std::function funcPtr = std::bind(max, std::placeholders::_1, std::placeholders::_2);
funcPtr(3, 5);
std::placeholders::_1表示占位符,_1表示第一个参数,_2表示第二个参数,以此类推。
以上代码效果完全是一样的,那有同学可能会怪异了,std::function<>类型不是可以直接赋值么,为啥还要std::bind,因为std::bind还有更多的功能,它可以改变函数的形式,比如:
int max(int x, int y);
std::function isGreatThen3 = std::bind(max, std::placeholders::_1, 3);
// 以下函数调用,也是调用到了max函数,5这个参数是第一个参数,所以它被安排到了x的位置,y参数在调用时没有提供,而是bind的时候提供了,所以y固定就是3
isGreadThen3(5);
std::placeholders::_1占位,指的是当函数被调用时,参数的位置,而在被调用的函数位置,是由std::bind的参数来决定的,std::bind的第一个参数是被调用的函数,后面的参数列表就是被调用函数的参数列表顺序。
std::bind也可以很方便的把成员函数指针和lambada表达式转化成std::function对象,比如:
lambada表达式
std::function func = [](){};
func();
成员函数指针
class MyClass
{
public:
void memberFunc(int x, int y);
};
MyClass obj;
std::function func = std::bind(&MyClass::memberFunc, &obj, std::placeholders::_1, std::placeholders::_2);
func(3, 5); // 实际调用的函数是obj.memberFunc(3, 5);
总结
std::function是C++通用的函数类型,它可以封装普通函数,成员函数和lambada表达式,让函数形式变得统一,在回调和定义函数集合时,都有非常强大的作用,使得C++代码变的简单。