一、std::function简介:
1、std::function是一个函数包装器,是一个类模板。
2、最早来自boost库,C++11纳入标准库。
3、包含头文件: #include <functional>
4、定义格式: std::function<Ret(Args...)>
(1)Ret为函数返回值类型,Args为函数参数类型。
(2)std::function包装的可调用对象具体看下面实例,特别注意不同实例的赋值对象是怎么定义的。
(3)std::function对象可被拷贝和转移。
5、std::function可取代函数指针,因可延迟函数的执行,特别适合作为回调函数使用。
二、std::bind简介:
1、std::bind是一个函数适配器,是一个函数模板。
2、包含头文件: #include <functional>
3、std::bind主要有两个作用:
(1) 将可调用对象和其参数绑定成一个仿函数。
(2) 只绑定部分参数,减少可调用对象传入的参数。
4、使用格式: Ret std::bind(F, Args...)
(1) F为可调用的对象,如函数指针。
(2) Args为可调用的对象要绑定的参数列表。
a、参数要么是命名空间占位符,std::placeholders::_1、std::placeholders::_2等。其中std::placeholders::_1表示调用时取实参列表中的第一个参数,std::placeholders::_2表示调用时取实参列表中的第二个参数。而std::placeholders::_1、std::placeholders::_2本身所在位置和可调用对象的参数位置是一一对应的。(不理解请看实例10)
b、参数要么绑定一个具体的值。调用时传入的实参不起作用。
c、注意,如果可调用的对象是类的成员函数,成员函数第一个参数是隐藏的this指针,所以 std::bind时别忘记了,但是std::function就不用考虑隐藏的this指针。
(3) Ret为一个新的函数对象,绑定后的结果Ret可以用std::function来保存。
三、实例1:包装普通函数
#include <iostream>
#include <functional>
using namespace std;
int g_Minus(int i, int j)
{
return i - j;
}
int main()
{
function<int(int, int)> f = g_Minus; //!!!!!!
//function<int(int, int)> f = bind(g_Minus, placeholders::_1, placeholders::_2); //!!!!!!也ok的。
cout << f(1, 2) << endl;
return 0;
}
四、实例2:包装普通模板函数
#include <iostream>
#include <functional>
using namespace std;
template<class T>
T g_Minus(T i, T j)
{
return i - j;
}
int main()
{
function<int(int, int)> f = g_Minus<int>; //!!!!!!
//function<int(int, int)> f = bind(g_Minus<int>, placeholders::_1, placeholders::_2); //!!!!!!也ok的。
cout << f(1, 2) << endl;
return 0;
}
五、实例3:包装Lambda表达式
#include <iostream>
#include <functional>
using namespace std;
auto g_Minus = [](int i, int j) {return i - j; };
int main()
{
auto Add = [](int i, int j) { return i + j; };
function<int(int, int)> f = g_Minus; //!!!!!!
cout << f(1, 2) << endl;
function<int(int, int)> f2 = Add; //!!!!!!
//function<int(int, int)> f2 = bind(Add, placeholders::_1, placeholders::_2); //!!!!!!也ok的。
cout << f2(1, 2) << endl;
return 0;
}
六、实例4:包装函数对象
#include <iostream>
#include <functional>
using namespace std;
struct Minus
{
int operator()(int i, int j)
{
return i - j;
}
};
int main()
{
function<int(int, int)> f = Minus(); //!!!!!!
//function<int(int, int)> f = bind(Minus(), placeholders::_1, placeholders::_2); //!!!!!!也ok的。
cout << f(1, 2) << endl;
return 0;
}
七、实例5:包装函数对象模板
#include <iostream>
#include <functional>
using namespace std;
template<class T>
struct Minus
{
T operator()(T i, T j)
{
return i - j;
}
};
int main()
{
function<int(int, int)> f = Minus<int>(); //!!!!!!
//function<int(int, int)> f = bind(Minus<int>(), placeholders::_1, placeholders::_2); //!!!!!!也ok的。
cout << f(1, 2) << endl;
return 0;
}
八、实例6:包装类静态函数
#include <iostream>
#include <functional>
using namespace std;
class Math
{
public:
static int Minus(int i, int j)
{
return i - j;
}
};
int main()
{
function<int(int, int)> f = &Math::Minus; //!!!!!!注: Math::Minus也可以用,但最好是&Math::Minus。
//function<int(int, int)> f = bind(&Math::Minus, placeholders::_1, placeholders::_2); //!!!!!!也ok的。
cout << f(1, 2) << endl;
return 0;
}
九、实例7:包装类静态函数模板
#include <iostream>
#include <functional>
using namespace std;
class Math
{
public:
template<class T>
static T Minus(T i, T j)
{
return i - j;
}
};
int main()
{
function<int(int, int)> f = &Math::Minus<int>; //!!!!!!注: Math::Minus<int>也可以用,但最好是&Math::Minus<int>。
//function<int(int, int)> f = bind(&Math::Minus<int>, placeholders::_1, placeholders::_2); //!!!!!!也ok的。
cout << f(1, 2) << endl;
return 0;
}
十、实例8:包装类对象成员函数
#include <iostream>
#include <functional>
using namespace std;
class Math
{
public:
int Minus(int i, int j)
{
return i - j;
}
};
int main()
{
Math m;
function<int(int, int)> f = bind(&Math::Minus, &m, placeholders::_1, placeholders::_2); //!!!!!!只能是&Math::Minus。
cout << f(1, 2) << endl;
return 0;
}
十一、实例9:包装类对象成员函数模板
#include <iostream>
#include <functional>
using namespace std;
class Math
{
public:
template<class T>
T Minus(T i, T j)
{
return i - j;
}
};
int main()
{
Math m;
function<int(int, int)> f = bind(&Math::Minus<int>, &m, placeholders::_1, placeholders::_2); //!!!!!!
cout << f(1, 2) << endl;
return 0;
}
十二、实例10: std::bind的作用
#include <iostream>
#include <functional>
using namespace std;
int Minus(int i, int j)
{
return i - j;
}
int main()
{
//(1)将可调用对象和其参数列表绑定
function<int(int, int)> f1 = bind(Minus, placeholders::_1, placeholders::_2);
cout << f1(1, 2) << endl; //-1
//(2)减少可调用对象传入的参数
function<int(int, int)> f2 = bind(Minus, 5, placeholders::_2);
cout << f2(1, 2) << endl; //3
function<int(int, int)> f3 = bind(Minus, placeholders::_1, 5);
cout << f3(1, 2) << endl; //-4
function<int(int, int)> f4 = bind(Minus, placeholders::_2, 5);
cout << f4(1, 2) << endl; //-3
function<int(int, int)> f5 = bind(Minus, 5, placeholders::_1);
cout << f5(1, 2) << endl; //4
function<int(int, int)> f6 = bind(Minus, 5, 3);
cout << f6(1, 2) << endl; //2
return 0;
}