0

I have the following types declared inside a class:

using ScriptFunction = std::function<void(std::string const&)>;
using Script_map = std::unordered_map<std::string, std::vector<ScriptFunction>>;

In this class i wish to store some member functions from other classes and call it like this:

void Manager::callback(std::string event, std::string data) {
    auto it = this->stored_func.find(event);                     //stored_func is a Script_map
    for (auto func : it->second) {
        func(data);
    }
}

The code works but, i want to change it so i can callback functions that receives 1 or 2 strings, or no argument at all. Is this possible?

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
Josty
  • 7
  • 2
  • There are multiple possibilities. You could use a union of all possible functions. You could wrap the functions in an object that has overloads for `operator()` in all possible argument counts. You could change the functions all such that they take always 2 arguments and supply ignored default arguments for those who don't need 2 arguments. It depends really on your use case. – n314159 Nov 12 '19 at 20:36
  • [See this question and answer](https://stackoverflow.com/questions/55930796/writing-a-generic-traverse-function-that-allows-the-flexibility-of-dealing-with/55930937#55930937). The trick is to move the parameters away from the parameter list and into members of a class. Then use `operator()` on the instance of the class. – PaulMcKenzie Nov 12 '19 at 21:08

1 Answers1

0

The are many possibilities. They are ranging from simple to extremely complicated, depending on what you really need. Given your example, probably the easiest would be to define a

struct event_data {
     std::string event;
     std::string data;
     std::string more;
};

Then let the functions take a reference to event_data:

using ScriptFunction = std::function<void(event_data&)>;
using Script_map = std::unordered_map<std::string, std::vector<ScriptFunction>>;

Now pass a reference to all the event data to each function. It is a reference, so there is no additional cost to let each func pick what they need:

void Manager::callback(const event_data& evt) {
    auto it = this->stored_func.find(evt.event);                             
    for (auto func : it->second) {
        func(evt);
    }
}
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185