C++高级用法--绑定器和函数对象
1.function
绑定器,函数对象,lambda表达式,都只能使用在一条语句中
希望使用一个函数类型实例化一个function
void() 函数类型
void(*)() 函数指针类型:表示指向返回值为空,无参数的函数的指针
基本语法:function <函数类型> 函数对象名称
如果希望function使用类内的成员函数,但是成员函数的调用又依赖于对象
所以需要加上一个作用域
因为对于类内的成员函数,都存在一个this指针,也就是类*
function <void(Test*,string)> 函数对象名称 = &Test::hello;
底层原理
2. C++11 STL中的绑定器
bind1st :operator() 的第一个形参变量绑定为一个确定的值
bind2st :operator() 的第二个形参变量绑定为一个确定的值
绑定器+二元函数对象 -》 一元函数对象
auto it1 = find_if(vec.begin(),vec.end(),bind1st(greater<int>(),70));
找第一个小于70的数字,返回其迭代器
绑定器底层实现原理
bind1st返回一个一元函数对象
第一个参数为二元函数对象,第二个为元素类型
底层实现
template<typename Compare,typename T>
class _mybind1st{
public:_mybind1st(Compare comp,T val):_comp(comp),_val(val){}bool operator()(const T& second){return _comp(_val,second);}
private:Compare _comp;T _val;
};template<typename Compare,typename T>
_mybind1st<Compare,T> mybind1st(Compare comp,const T& val){return _mybind1st<Compare,T>(comp,val);
}
绑定其返回的结果还是一个函数对象
#include <bits/stdc++.h>
using namespace std;//绑定器的返回结果还是一个函数对象
void hello(string str){cout<<str<<endl;}
class Test{
public:int sum(int a,int b){return a+b;}
};
int main(){bind(hello,"wjm041006")();int s = bind(&Test::sum,Test(),20,30)();cout<<s;
}
参数占位符:绑定器最多可以绑定二十个参数
意思是我不知道该参数是什么,等待用户传递
#include <bits/stdc++.h>
using namespace std;//绑定器的返回结果还是一个函数对象
void hello(string str){cout<<str<<endl;}int main(){bind(hello,placeholders::_1)("hello world");
}
绑定器出了语句无法继续使用
我们通过定义function来获取绑定器的返回的函数对象
#include <bits/stdc++.h>
using namespace std;//绑定器的返回结果还是一个函数对象
void hello(string str){cout<<str<<endl;}int main(){function<void(string)> func1 = bind(hello,placeholders::_1);func1("wjm041006");
}
3.bind和function实现线程池
#include <bits/stdc++.h>
using namespace std;//线程类
class Thread{
public:Thread(function<void(int)> func,int id) :_func(func),_id(id){}thread start(){thread t(_func,_id);return t;}
private:function<void(int)> _func;int _id;
};//线程池类
class ThreadPool{
public:ThreadPool(){}~ThreadPool(){//释放堆资源for(int i=0;i<_pool.size();++i){delete _pool[i];}}//开启线程池void startPool(int size){for(int i=0;i<size;++i){_pool.push_back(new Thread(bind(&ThreadPool::runInThread,this,placeholders::_1),i));}for(int i=0;i<size;++i){_handler.push_back(_pool[i]->start());}for(thread &t:_handler){t.join();}}
private:vector<Thread*> _pool;vector<thread> _handler;//把这个成员方法充当线程函数void runInThread(int id){cout<<"run Thread:id:"<<id<<endl;}};int main(){ThreadPool mypool;mypool.startPool(10);
}