I am trying to implement a high-performance event bus. One part of the code deals with wrapping Callables of different signatures to a common wrapper so that I can keep them in a container. The respective classes look somewhat like this:
struct CallbackWrapperBase
{
void instantCall(const EventBase&) const = 0;
void delayedCall(const EventBase&) const = 0;
};
template <typename EventType>
struct CallbackWrapper : CallbackWrapperBase
{
CallbackWrapper(Callback<EventType> callback) : m_callback(callback) {}
void delayedCall(const EventBase& event) const { m_callback(static_cast<const DelayedEvent<EventType>&>(event).getEvent()); }
void instantCall(const EventBase& event) const { m_callback(static_cast<const InstantEvent<EventType>&>(event).getEvent()); }
Callback<EventType> m_callback;
};
For optimization purposes, in order to avoid the overhead from the virtual calls, I made the following changes:
struct CallbackWrapperBase
{
typedef void (CallbackWrapperBase::* Base_fun)(const EventBase&) const;
Base_fun instantCall;
Base_fun delayedCall;
};
template <typename EventType>
struct CallbackWrapper : CallbackWrapperBase
{
CallbackWrapper(Callback<EventType> callback) : m_callback(callback)
{
CallbackWrapperBase::instantCall = static_cast<Base_fun>(&CallbackWrapper::instantCall);
CallbackWrapperBase::delayedCall = static_cast<Base_fun>(&CallbackWrapper::delayedCall);
}
void delayedCall(const EventBase& event) const { m_callback(static_cast<const DelayedEvent<EventType>&>(event).getEvent()); }
void instantCall(const EventBase& event) const { m_callback(static_cast<const InstantEvent<EventType>&>(event).getEvent()); }
Callback<EventType> m_callback;
};
However I am not sure whether the casts are standard-compliant. Any feedback on this matter is much appreciated!
Aucun commentaire:
Enregistrer un commentaire