[C++] function wrapper

Use of function wrapper

functionWrapper usage format

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

You are given an array of strings tokensrepresenting an arithmetic expression in reverse Polish notation.

Please evaluate this expression. Returns an integer representing the value of the expression.

Notice:

  • Valid operators are '+', '-', '*'and '/'.
  • Each operand (operand) can be an integer or another expression.
  • Division between two integers is always truncated towards zero .
  • There is no division by zero operation in the expression.
  • The input is an arithmetic expression expressed in reverse Polish notation.
  • The answer and all intermediate calculation results can be represented as 32-bit integers.

Example 1:

输入:tokens = ["2","1","+","3","*"]
输出:9
解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9

Example 2:

输入:tokens = ["4","13","5","/","+"]
输出:6
解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6

Example 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

hint:

  • 1 <= tokens.length <= 104
  • tokens[i]is an operator ( "+", "-", "*"or "/"), or [-200, 200]an integer in the range

Reverse Polish expression:

The reverse Polish expression is a suffix expression. The so-called suffix means that the operator is written at the end.

  • The commonly used calculation is an infix expression, such as ( 1 + 2 ) * ( 3 + 4 ).
  • The reverse Polish expression of this equation is written as ( ( 1 2 + ) ( 3 4 + ) * ).

The reverse Polish expression has the following two main advantages:

  • After removing the parentheses, the expression is unambiguous. Even if the above formula is written, 1 2 + 3 4 + * the correct result can be calculated based on the order.
  • Suitable for stack operations: when a number is encountered, it is pushed onto the stack; when an operator is encountered, the two numbers on the top of the stack are taken out for calculation, and the result is pushed onto the stack.

If you use conventional methods, there will be many 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();
    }
};

But functionit will be much simpler if you introduce the code

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

Usedfunction to receive an Lambdaexpression.

Function implementation principle

//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...)Is an alias for a function pointer type.

_pfuncis a function pointer.

The constructor can directly copy the address of the function pointer to get the address of the function.

A... is a variable parameter package

Guess you like

Origin blog.csdn.net/AkieMo/article/details/132163802