【C++】function包装器

简介: 【C++】function包装器

function包装器的使用

function包装器的使用格式

function<返回类型(参数)>

#include<iostream>
#include<functional>
using namespace std;
class test
{
public:
  static void func1(int a,int b)
  {
    cout << a + b << endl;
  }
  void func2(int a, int  b)
  {
    cout << a + b << endl;
  }
};
int Add(int a, int b)
{
  return a + b;
}
class test1
{
public:
  int operator()(int a, int  b)
  {
    return a + b;
  }
};
int main(void)
{
  function<void(int, int)>f1 = &test::func1;
  f1(2, 3);
  function<void(test,int, int)>f2 = &test::func2;
  f2(test(),5, 7);
  function<int(int, int)>f3 = Add;
  cout << f3(9, 10) << endl;
  function<int(int,int)>f4=[](int a, int b)->int {return a + b; };
  cout << f4(10, 12) << endl;
  function<int(int, int)>f5 = test1();
  cout << f5(13, 14)<<endl;
  return 0;
}

给你一个字符串数组tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。

请你计算该表达式。返回一个表示表达式值的整数。

注意:

  • 有效的算符为 '+''-''*''/'
  • 每个操作数(运算对象)都可以是一个整数或者另一个表达式。
  • 两个整数之间的除法总是 向零截断
  • 表达式中不含除零运算。
  • 输入是一个根据逆波兰表示法表示的算术表达式。
  • 答案及所有中间计算结果可以用 32 位 整数表示。

示例 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

提示:

  • 1 <= tokens.length <= 104
  • tokens[i] 是一个算符("+""-""*""/"),或是在范围 [-200, 200] 内的一个整数

逆波兰表达式:

逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面。

  • 平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 )
  • 该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * )

逆波兰表达式主要有以下两个优点:

  • 去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。
  • 适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中

如果用常规方法会有很多switch case

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<long long>st;
        for(auto& str: tokens)
        {
            if(str=="+"||str=="-"
            ||str=="*"||str=="/")
            {
                long long right=st.top();
                st.pop();
                long long left=st.top();
                st.pop();
                switch(str[0])
                {
                    case'+':
                    st.push(left+right);
                    break;
                    case'-':
                    st.push(left-right);
                    break;
                    case'*':
                    st.push(left*right);
                    break;
                    case'/':
                    st.push(left/right);
                    break;
                }
            }else
            {
                st.push(stoll(str));
            }
        }
        return st.top();
    }
};

但如果引入function代码就会简单很多了

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        map<string,function<long long(long long,long long )>>opFunc
        {
            {"+",[](long long a,long long b)->long long{return a+b;}},
            {"-",[](long long a,long long b)->long long{return a-b;}},
            {"*",[](long long a,long long b)->long long{return a*b;}},
            {"/",[](long long a,long long b)->long long{return a/b;}},
        };
        stack<long long>res;
        for(auto &str:tokens)
        {
            if(opFunc.find(str)!=opFunc.end())
            {
                int right=res.top();
                res.pop();
                int left=res.top();
                res.pop();
                res.push(opFunc[str](left,right));
            }else
            {
                res.push(stoll(str));
            }
        }
        return res.top();
    }
};

function去接收一个Lambda表达式。

function的实现原理

//R为返回值类型,A是传入的参数类型
template<typename R, typename... A>
class myfunction<R(A...)>
{
public:
  using PFUNC = R(*)(A...);
  myfunction(PFUNC pfunc) :_pfunc(pfunc) {}
  R operator()(A... arg)
  {
    return _pfunc(arg...); // hello(arg)
  }
private:
  PFUNC _pfunc;
};

PFUNC = R(*)(A...)是一个函数指针类型的别名。

_pfunc是一个函数指针。

构造函数直接拷贝函数指针的地址就能拿到函数的地址了。

A…是一个可变参数包

目录
相关文章
|
2月前
|
设计模式 安全 数据库连接
【C++11】包装器:深入解析与实现技巧
本文深入探讨了C++中包装器的定义、实现方式及其应用。包装器通过封装底层细节,提供更简洁、易用的接口,常用于资源管理、接口封装和类型安全。文章详细介绍了使用RAII、智能指针、模板等技术实现包装器的方法,并通过多个案例分析展示了其在实际开发中的应用。最后,讨论了性能优化策略,帮助开发者编写高效、可靠的C++代码。
42 2
|
8月前
|
存储 编译器 C语言
从C语言到C++_34(C++11_下)可变参数+ lambda+function+bind+笔试题(下)
从C语言到C++_34(C++11_下)可变参数+ lambda+function+bind+笔试题
117 5
|
4月前
|
存储 算法 程序员
C++ 11新特性之function
C++ 11新特性之function
72 9
|
3月前
|
C++ 容器
函数对象包装器function和bind机制
函数对象包装器function和bind机制
28 0
|
6月前
|
存储 C++ 运维
开发与运维函数问题之使用C++标准库中的std::function来简化回调函数的使用如何解决
开发与运维函数问题之使用C++标准库中的std::function来简化回调函数的使用如何解决
62 6
|
6月前
|
存储 C++
【C++】string类的使用③(非成员函数重载Non-member function overloads)
这篇文章探讨了C++中`std::string`的`replace`和`swap`函数以及非成员函数重载。`replace`提供了多种方式替换字符串中的部分内容,包括使用字符串、子串、字符、字符数组和填充字符。`swap`函数用于交换两个`string`对象的内容,成员函数版本效率更高。非成员函数重载包括`operator+`实现字符串连接,关系运算符(如`==`, `&lt;`等)用于比较字符串,以及`swap`非成员函数。此外,还介绍了`getline`函数,用于按指定分隔符从输入流中读取字符串。文章强调了非成员函数在特定情况下的作用,并给出了多个示例代码。
|
8月前
|
程序员 编译器 C++
C++中的函数重载(Function Overloading)
C++中的函数重载(Function Overloading)
90 2
|
8月前
|
算法 编译器 C语言
从C语言到C++_34(C++11_下)可变参数+ lambda+function+bind+笔试题(中)
从C语言到C++_34(C++11_下)可变参数+ lambda+function+bind+笔试题
72 2
|
8月前
|
算法 编译器 C语言
从C语言到C++_34(C++11_下)可变参数+ lambda+function+bind+笔试题(上)
从C语言到C++_34(C++11_下)可变参数+ lambda+function+bind+笔试题
55 1
|
8月前
|
存储 算法 对象存储
【C++入门到精通】function包装器 | bind() 函数 C++11 [ C++入门 ]
【C++入门到精通】function包装器 | bind() 函数 C++11 [ C++入门 ]
106 1

热门文章

最新文章

下一篇
开通oss服务