当前位置: 首页 > news >正文

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);
}

相关文章:

  • C++跨平台开发经验与解决方案
  • 备战!全国青少年信息素养大赛图形化编程-省赛——求最小公倍数
  • 院士方复全数学命题证明采用预期理由和循环论证以及类比的错误方法
  • 【C++进阶篇】C++容器完全指南:掌握set和map的使用,提升编码效率
  • 在Gitee中配置SSH公钥,建立远程仓库和本地仓库的连接
  • 【U-boot 命令使用】
  • 5月18日day29打卡
  • MCP - Cline 接入 高德地图 Server
  • 论信息系统项目的采购管理
  • 每天学一个Linux命令:compgen
  • Linux梦开始的地方
  • 一文读懂-嵌入式Ubuntu平台
  • Linux基础第三天
  • FAST-DDS源码分析PDP(一)
  • AGI大模型(24):通过LangChain的接口来调用OpenAI对话
  • 第11章 JDBC与MySQL数据库
  • 做什么, what to do?
  • 如何修改服务器管理员账号名和密码(1)
  • Redis实现分布式锁的进阶版:Redisson实战指南
  • 【MySQL】02.数据库基础
  • 习近平:坚持科学决策民主决策依法决策,高质量完成“十五五”规划编制工作
  • 上海位居全球40城科技传播能力第六名
  • 义乌至迪拜“铁海快线+中东快航”首发,物流成本降低18%
  • 黑龙江省政府副秘书长许振宇,拟任正厅级领导
  • 奥迪车加油时频繁“跳枪”维修两年未解决,4S店拒退换:可延长质保
  • 最新研究:新型合成小分子可“精准杀伤”癌细胞