C++多态工厂如何从字符串名称和参数映射构建函数对象
#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";
}
我正在尝试创建一个类似 Python 的 C++ 库,用户将在其中提供字符串和参数的 map
。代码会将映射解析为函数,然后执行函数。最重要的是,我需要能够编写:
std::any param_map; // = something, doesn't matter here
FunctionBase *myfunc = new functionMapping["myfunc"](param_map);
给定示例中的代码,
map<string, ???> functionMapping;
Edit: 的值类型应该是什么:使用丑陋的 if 语句添加了等效的解决方案
#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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用基于模板的抽象工厂。这是非常通用的,可以用于不同类型的键和值。
也许下面的通用代码可以让您了解如何实现您的工厂。
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.
答案是使用 lambda 和 std::function
The answer is using
lambda
andstd::function