具有不同参数类型的回调并存储类型

时间:2015-10-22 21:31:45

标签: c++ c++11 dictionary

我有一个通信库,它应该根据收到的命令类型调用回调(或处理程序)。我将处理程序存储在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));

2 个答案:

答案 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在运行时获取有关特定类型的一些信息。