I have a communication library, that should invoke callbacks (or handlers) based on a received command type. I am storing handlers in a std::map
(command as a key, handler as a value).
These handlers need to have different parameter types. There is always only one handler parameter, and this parameter inherits fromBaseType
. So I have following typedefs and handlers:
class Comm {
typedef std::function<void(BaseType*)> Handler;
typedef std::map<Command, Handler> Handlers;
void HandleHandshake(IntType*); // IntType inherits from BaseType
};
Unfortunately I cannot store handler HandleHandshake
in the Handlers
type. I can only store a handler that has parameter of type BaseType*
. I cannot use std::function<void()>
to bind different arguments since I need to have access to its argument_type
(Otherwise I wouldn't be able to pass proper data type when invoking the handler.).
Is there any way of achieving what I want to achieve? (Storing handlers of different parameter types, and also storing the type for further use.)
To show example of calling the handler:
// 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));
You could always store a lambda that does a static_cast
. For example:
template <typename T=BaseType, typename F>
void store(Command c, F function)
{
Handlers[c] = [function](BaseType* obj){
function(static_cast<T*>(obj));
});
}
I've worked on something similar before. This is what I would do:
typedef std::function<void(BaseType*)> Handler;
typedef std::map<Command, Handler> Handlers;
Then I would have each handler take a pointer to BaseType* so that I can store it in my map.
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);
// ...
}
You can't store a type object like you can in C# and then use it to create objects of that type. You can use typeinfo to get some information about a particular type at runtime.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With