#include <cassert>
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <any>
#include <functional>
#include <type_traits>
using namespace std;
using MapAny = map<string, any>;
class FunctionBase {
public:
FunctionBase() {}
FunctionBase(const MapAny ¶m_maps) {}
virtual any operator()(const any &data) const = 0;
};
class Func1 : public FunctionBase {
private:
int a,b;
public:
Func1(const MapAny ¶m_map) {
a = any_cast<int>(param_map.at("a"));
b = any_cast<int>(param_map.at("b"));
}
virtual any operator()(const any &data) const override {
// calculate some F1(data, a, b)
return a + b;
}
};
class Func2 : public FunctionBase {
private:
float c,d;
public:
Func2(const MapAny ¶m_map) {
c = any_cast<float>(param_map.at("c"));
d = any_cast<float>(param_map.at("d"));
}
virtual any operator()(const any &data) const override {
// calculate some F2(data, a, b)
return c * d;
}
};
FunctionBase* functionFactory(string name, const MapAny ¶m_map)
{
if (name=="func1") return new Func1(param_map);
if (name=="func2") return new Func2(param_map);
return nullptr;
}
int main()
{
// map<string, ???> functionMapping;
// functionMapping["func1"] = ...
// functionMapping["func2"] = ...
vector<float> data;
MapAny param_map1;
param_map1["a"] = 3;
param_map1["b"] = 5;
FunctionBase* func1 = functionFactory("func1", param_map1); //functionMapping["func1"](param_map1);
assert(any_cast<int>(func1->operator()(data))==8);
MapAny param_map2;
param_map2["c"] = 2.0f;
param_map2["d"] = 4.0f;
FunctionBase* func2 = functionFactory("func2", param_map2); //functionMapping["func2"](param_map2);
assert(any_cast<float>(func2->operator()(data))==8.0);
cout << "Correct\n";
}
I'm trying to make a Python-like C++ library, where user will give a map
of string and parameters. The code will parse the map to functions, then execute the functions. Most importantly, I need to be able to write:
std::any param_map; // = something, doesn't matter here
FunctionBase *myfunc = new functionMapping["myfunc"](param_map);
Given the code in the example, what should be the value type of
map<string, ???> functionMapping;
Edit: added an equivalent solution using ugly if-statement
You may use an template based abstract factory. This is very generic and can be used for different types of keys and values.
Maybe the following generic code gives you an idea, how you could implement your factory.