C++11的std::function和std::bind

一、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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小马兰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值