c++ - 在地图中存储通用回调
问题描述
我想创建一个 id / 通用回调映射,但我不知道它是否可行。我的想法是这样的:不同的国王od对象
class Class1
{
public:
bool run(const int &temp){
std::cout << "worker1:" << temp << std::endl;
return 0;
}
};
class Class2
{
public:
bool run(const std::string &temp){
std::cout << "worker2:" << temp << std::endl;
return 0;
}
};
回调对象的模板:
template <typename ReturnType, typename... Args>
class Callback
{
private:
std::function<ReturnType> _function;
public:
Callback(std::function < ReturnType(Args...)> function)
: _function(function){}
auto run(Args... args)
{
return function(std::forward<Args>(args)...);
}
};
使用示例
int main() {
Class1 class1;
Class2 class2;
std::map<int, Callback> cbs;
cbs[1] = std::bind(&Class1::run, &class1, std::placeholders::_1));
cbs[2] = std::bind(&Class1::run, &class1, std::placeholders::_1));
cbs[1].run(1);
cbs[2].run("string msg");
}
解决方案
也许你可以用std::any
我创建了工厂,在其中存储了带有地图中任何签名的函数。
请看一下,如果它可以给你一个想法。否则我会删除这个答案
#include <iostream>
#include <map>
#include <utility>
#include <any>
// Some demo classes ----------------------------------------------------------------------------------
struct Base {
Base(int d) : data(d) {};
virtual ~Base() { std::cout << "Destructor Base\n"; }
virtual void print() { std::cout << "Print Base\n"; }
int data{};
};
struct Child1 : public Base {
Child1(int d, std::string s) : Base(d) { std::cout << "Constructor Child1 " << d << " " << s << "\n"; }
virtual ~Child1() { std::cout << "Destructor Child1\n"; }
virtual void print() { std::cout << "Print Child1: " << data << "\n"; }
};
struct Child2 : public Base {
Child2(int d, char c, long l) : Base(d) { std::cout << "Constructor Child2 " << d << " " << c << " " << l << "\n"; }
virtual ~Child2() { std::cout << "Destructor Child2\n"; }
virtual void print() { std::cout << "Print Child2: " << data << "\n"; }
};
struct Child3 : public Base {
Child3(int d, long l, char c, std::string s) : Base(d) { std::cout << "Constructor Child3 " << d << " " << l << " " << c << " " << s << "\n"; }
virtual ~Child3() { std::cout << "Destructor Child3\n"; }
virtual void print() { std::cout << "Print Child3: " << data << "\n"; }
};
using UPTRB = std::unique_ptr<Base>;
template <class Child, typename ...Args>
UPTRB createClass(Args...args) { return std::make_unique<Child>(args...); }
// The Factory ----------------------------------------------------------------------------------------
template <class Key, class Object>
class Factory
{
std::map<Key, std::any> selector;
public:
Factory() : selector() {}
Factory(std::initializer_list<std::pair<const Key, std::any>> il) : selector(il) {}
template<typename Function>
void add(Key key, Function&& someFunction) { selector[key] = std::any(someFunction); };
template <typename ... Args>
Object create(Key key, Args ... args) {
if (selector.find(key) != selector.end()) {
return std::any_cast<std::add_pointer_t<Object(Args ...)>>(selector[key])(args...);
}
else return nullptr;
}
};
int main()
{
Factory<int, UPTRB> factory{
{1, createClass<Child1, int, std::string>},
{2, createClass<Child2, int, char, long>}
};
factory.add(3, createClass<Child3, int, long, char, std::string>);
// Some test values
std::string s1(" Hello1 "); std::string s3(" Hello3 ");
int i = 1; const int ci = 1; int& ri = i; const int& cri = i; int&& rri = 1;
UPTRB b1 = factory.create(1, 1, s1);
UPTRB b2 = factory.create(2, 2, '2', 2L);
UPTRB b3 = factory.create(3, 3, 3L, '3', s3);
b1->print();
b2->print();
b3->print();
b1 = factory.create(2, 4, '4', 4L);
b1->print();
return 0;
}
推荐阅读
- java - 无法从 CentOS 8 服务器使用 MS JDBC 驱动程序连接到 SQL Server 服务器:SSL 错误但未使用安全连接
- python - 使用 python opencv 检测刻度线
- mysql - 有没有办法在 SQL 中每分钟只选择第一项?
- ignite - 拓扑无效时如何禁用对点燃缓存的所有操作
- kframework - 实施评估上下文列表?
- python - 使用 folium 从数据框制作等值线图
- c - GTK+,基于 C 的软件,图像损坏
- java - 如何防止对象被垃圾收集
- mapbox - 如何在 iOS 上动态更新 Mapbox 的 MGLShapeSource 的 MGLPointFeature 属性值?
- python - 在绘制图像之前打印文本 (matplotlib/imageio)