0


C++包装器

文章目录

概述

包装器可以对一个可调用对象进行包装
可调用对象包括

  • lambda表达式
  • 仿函数
  • 函数指针

使用包装器可以避免模板实例化出多份代码,可以提高效率

function

function的使用

function可以使用构造函数进行初始化,也能用赋值进行初始化
function< ( …)>:function括号里面就是包装的函数的类型对应的参数类型,括号外面就是函数的返回值

仿函数

structFunctor{doubleoperator()(double i){return i /2;}};intmain(){double m=10.1;
    function<double(double)> f2 =Functor();//仿函数对象
    cout<<f2(m)<<endl;return0;}

Lambda表达式

intmain(){double m=10.1;
    function<double(double)> f2 =[](double i){return i/2;};//Lambda表达式
    cout<<f2(m)<<endl;return0;}

函数指针

voidl(int& x){
    x+=2;
    cout<<"222"<<endl;}voiddemo4(){int x=2;
    function<void(int&)> s=l;s(x);
    cout<<x<<endl;// cout<<ret<<endl;}

类成员函数

classPlus{public:staticdoublefI(double x){return x;}doublef(double i){return i /2;}};intmain(){//只要是成员函数就要加&
   function<double(double)> f3 =&Plus::fI;//静态的成员函数//还可以包装成员函数
   cout <<f2(10)<< endl;//对于非静态的成员函数
   function<double(Plus,double)> ff =&Plus::f;//非静态的成员函数要多加一个Plus,因为有this指针
   cout <<ff(Plus(),123)<< endl;//使用的时候要多添加一个类对象(可以是匿名对象)return0;}

function的实战

逆波兰表达式

根据 逆波兰表示法,求表达式的值。
有效的算符包括 +、-、、/ 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
注意 两个整数之间的除法只保留整数部分。
可以保证给定的逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
示例 1:
输入:tokens = [“2”,“1”,“+”,“3”,"“]
输出:9
解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
示例 2:
输入:tokens = [“4”,“13”,“5”,”/“,”+“]
输出:6
解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6
示例 3:
输入:tokens = [“10”,“6”,“9”,“3”,”+“,”-11",“
“,”/“,”
”,“17”,“+”,“5”,“+”]
输出:22
解释:该算式转化为常见的中缀算术表达式为:
((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22

题解:如果是操作数就入栈,如果是操作符,就把栈顶的两个数取出来进行处理

我们可以使用map,命令和函数可以进行映射,映射到的为function,因为function对于函数指针,lambda表达式,仿函数都可以包装,所以就可以了,一个命令对应一个函数

classSolution{public:intevalRPN(vector<string>&tokens){//使用列表初始化//包装器,只要是可调用对象就行了,很方便//使用包装器之后就能用函数映射了

        map<string, function<int(int,int)>> opMapFunc;//动作和函数映射的map//命令增加了只需要加这个map这里,一个命令对应一个函数

        opMapFunc["+"]=[](int a,int b){return a + b;};//包装器,初始化用函数指针,仿函数,lambda表达式
        opMapFunc["-"]=[](int a,int b){return a - b;};//包装器,初始化用函数指针,仿函数,lambda表达式
        opMapFunc["*"]=[](int a,int b){return a * b;};//包装器,初始化用函数指针,仿函数,lambda表达式
        opMapFunc["/"]=[](int a,int b){return a / b;};//包装器,初始化用函数指针,仿函数,lambda表达式//也可以用列表初始化

        stack<int> s;int i =0;int top;//逆波兰表达式,一个命令和一个函数的映射关系就可以用包装器来解决for(int i =0; i < tokens.size(); i++){
            string &str = tokens[i];//用别名弄,减少了拷贝// str为操作数// map里面为操作数就找不到if(opMapFunc.find(str)== opMapFunc.end()){//说明就是操作数
                s.push(stoi(str));//入栈}else{//这里就是操作符int left = s.top();
                s.pop();int right = s.top();
                s.pop();//取出来了数据
                s.push(opMapFunc[str](left, right));}}return s.top();}};

bind

  1. bind可以对function绑定的函数调整参数的顺序
  2. bind可以调整参数的个数(比如将包装之后的函数固定一个参数为某个东西,就不需要我们再手动去添加)
// bind也是一个函数包装器//接收一个可调用对象,生成一个可调用对象intsub(int a,int b){return a - b;}classsubber{public:intSub(int a,int b){return a - b;}};voiddemo3(){
    function<int(int,int)> f = sub;
    cout <<f(10,3)<< endl;//调整参数的顺序
    function<int(int,int)> f1 =bind(sub,placeholders::_1,placeholders::_2);//这个就是啥都没做
    cout <<f1(10,3)<< endl;
    function<int(int,int)> f3 =bind(sub,placeholders::_2,placeholders::_1);//参数顺序调换了//这里的_1就是把原来的第一个参数换到现在的位置,_2就是把原来的第2个参数换到现在的第一个//这个就是可以把库里面的用的不习惯的函数,切换参数顺序//主要是通过绑定来进行调整参数个数

    cout <<f3(10,3)<< endl;
    function<int(subber,int,int)> f4 =&subber::Sub;
    cout <<f4(subber(),10,3)<< endl;//使用了用还要加一个对象//每次都这样用很烦
    function<int(int,int)> f5 =bind(&subber::Sub,subber(),placeholders::_1,placeholders::_2);//这样子进行绑定,第一个参数就绑死了,使用的时候就不需要再去添加
    cout <<f5(10,3)<< endl;//假如说第一个参数都是一样的
    function<int(int)> f6=bind(&subber::Sub,subber(),100,placeholders::_1);//第一个参数都是100
    cout<<f6(20)<<endl;//这里也能用auto进行接收}
classA{public:A()=default;voidl(int&x){
    x +=2;
    cout <<"222"<< endl;}voidll(int&x){
    x +=2;
    cout <<"222"<< endl;}};intmain(){
    map<int, function<void(int&)>> lll ={{X,bind(&A::ll,A(), placeholders::_1)},{2,bind(&A::l,A(),placeholders::_1)}};
    lll[X](m);//映射包装器与bind,可以使得我们在用的时候,对类立案的参数就不要写了return0;}
标签: c++ 开发语言

本文转载自: https://blog.csdn.net/m0_61567378/article/details/126457494
版权归原作者 Zevin~ 所有, 如有侵权,请联系我们删除。

“C++包装器”的评论:

还没有评论