Open In App

C++ Map of Functions

Improve
Improve
Like Article
Like
Save
Share
Report

Prerequisites:

  1. Functions in C++
  2. Map in C++

Maps in C++ are a very useful data structure for storing key-value pairs. A map is the best way to store where we can directly find and access the value using a key with the best time complexity.

However, did you know that you can also store functions as values in a C++ map? That’s right – it is possible to use a map to store and quickly access a set of functions that need to be called at different times in a program. Let’s check the map of functions.

Map of functions

Map of functions is the type of map where rather than the value we attach a function with the key. This can be especially useful if you need to call a variety of functions at different times in your program, as it allows you to easily associate a name with each function and quickly look up and call the function you need.

Syntax:

std::function<return_type(arg_type1, arg_type2, ...)> var_name;

In this code, return_type is the return type of the function, and arg_type1, arg_type2, etc. are the types of the function arguments.

To create a map of functions, we will first need to define the function signature that we want to use. In this case, we want to store functions that take two long arguments and return a long value. We can use the function template from the functional header file to define a variable that can store such a function:

// first create a function template
using func=function<long(long,long)>;


// create a map object
unordered_map<string,func> mp{
    {"+", plus<long>()},
    {"-", minus<long>()},
    {"/", divides<long>()},
    {"*", multiplies<long>()}
};

In this code, the functions plus, minus, divide, and multiplies are added to the map object map with string keys “+”, “-“, “/”, and “*”, respectively.

To call a function stored in the map, you can use the array access operator [] to retrieve the function pointer and the function call operator () to call the function. 

For example:

long result = map["+"](2, 3);   //  5
long result1 = map["-"](2, 3);  // -1
long result2= map["*"](2, 3);   //  6
long result3 = map["/"](6, 3);  //  2

Using a map to store functions has several advantages. It allows you to easily add or remove functions at runtime, and it also allows you to easily associate a name with each function, which can make it easier to understand and maintain the code. Let’s understand it with one problem.

Problem Statement: 

You have been given an array of strings called tokens that represent an arithmetic expression written in Reverse Polish Notation (RPN). Your task is to evaluate this expression and return the result as an integer. Each operand may be an integer or another RPN expression. When dividing two integers, the result will always be truncated toward zero. You can assume that the input represents a valid RPN expression and that there will not be any division by zero.

Let us check some test cases to understand.

Case 1:

Input: ["2", "1", "+", "3", "*"]
Output: 9
Explanation: ((2 + 1) * 3) = 9

Case 2:

Input: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"]
Output: 22
Explanation: ((10 * (6 / ((9 + 3) * -11))) + 17) + 5 = 22

Example:

C++




// C++ Program to implement
// map of functions
#include <bits/stdc++.h>
using namespace std;
 
// Define a type alias for a function that takes two longs
// and returns a long
using func = function<long(long, long)>;
 
// Create a map that maps strings to functions
map<string, func> mp{
      // Plus function from functools
    { "+", plus<long>() },
      // Minus function from functools
    { "-", minus<long>() },
       // Divides function from functools
    { "/", divides<long>() },
     // Multiplies function from functools
    { "*", multiplies<long>() }
};
 
// Function to evaluate a Reverse Polish Notation (RPN)
// expression
int evalRPN(vector<string>& A)
{
    // Create a stack to store the operands
    stack<long> s;
 
    // Iterate over the elements in the RPN expression
    for (auto i : A) {
        // If the element is not an operator, it is an
        // operand Convert it to an integer and push it onto
        // the stack
        if (!mp[i]) {
            s.push(stoi(i));
        }
        // If the element is an operator, pop the top two
        // operands from the stack Perform the operation and
        // push the result back onto the stack
        else {
            auto num1 = s.top();
            s.pop();
            auto num2 = s.top();
            s.pop();
            s.push(mp[i](num2, num1));
        }
    }
   
    // Return the result, which is the top element of the
    // stack
    return s.top();
}
 
int main()
{
    // Test the evalRPN function with an RPN expression
    vector<string> A
        = { "10", "6", "9""3", "+", "-11", "*",
            "/""*", "17", "+", "5", "+" };
 
    int answer = evalRPN(A);
    cout << answer << endl;
   
    return 0;
}


Output

22

Time complexity: O(N) // here N is  the size of vector A;

Auxiliary space: O(N).



Last Updated : 23 Jan, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads