我有一个通信库,它应该根据收到的命令类型调用回调(或处理程序)。我将处理程序存储在std::map
中(命令作为键,处理程序作为值)。
这些处理程序需要具有不同的参数类型。始终只有一个处理程序参数,此参数继承自BaseType
。所以我有以下typedef和处理程序:
class Comm {
typedef std::function<void(BaseType*)> Handler;
typedef std::map<Command, Handler> Handlers;
void HandleHandshake(IntType*); // IntType inherits from BaseType
};
很遗憾,我无法将处理程序HandleHandshake
存储在Handlers
类型中。我只能存储参数类型为BaseType*
的处理程序。我不能使用std::function<void()>
来绑定不同的参数,因为我需要访问它的argument_type
(否则我在调用处理程序时无法传递正确的数据类型。)。
有没有办法实现我想要实现的目标? (存储不同参数类型的处理程序,并存储该类型以供进一步使用。)
显示调用处理程序的示例:
// I parsed a command. Handler of this command should take IntType as a parameter.
m_Handlers[cmd](IntType(some_data));
// But, I don't really know that it is IntType, I only have my map of handlers.
// I want something like this:
m_Handlers[cmd](m_Handlers[cmd]::argument_type(some_data));
答案 0 :(得分:3)
您始终可以存储执行static_cast
的lambda。例如:
template <typename T=BaseType, typename F>
void store(Command c, F function)
{
Handlers[c] = [function](BaseType* obj){
function(static_cast<T*>(obj));
});
}
答案 1 :(得分:0)
我之前曾做过类似的事情。这就是我要做的事情:
typedef std::function<void(BaseType*)> Handler;
typedef std::map<Command, Handler> Handlers;
然后我会让每个处理程序获取一个指向BaseType *的指针,以便我可以将它存储在我的地图中。
void MyIntHandler(BaseType* b)
{
// we know what kind of information should be passed into this method
// so we can just cast to the correct type
auto data = static_cast<IntType*>(b);
// do something with data
}
void MyStringHandler(BaseType* b)
{
auto data = static_cast<StringType*>(b);
// ...
}
您无法在C#中存储类型对象,然后使用它来创建该类型的对象。您可以使用typeinfo在运行时获取有关特定类型的一些信息。