Reputation: 9183
I have an interface like this (except much much lengthier than this in the real library code)
struct IFoo
{
virtual void onA(A& a) = 0;
virtual void onB(A& a) = 0;
virtual void onC(A& a) = 0;
};
and it is common for me to implement different listeners of IFoo
. Because of this, I designed a helper class like this one:
template <class T>
struct IFooHelper {
virtual void onA(A& a) { static_cast<T*>(this)->onGeneric(a); }
virtual void onB(B& b) { static_cast<T*>(this)->onGeneric(b); }
virtual void onC(C& c) { static_cast<T*>(this)->onGeneric(c); }
};
so now, when I have a lot of common behavior in a listener, rather than having to provide a virtual override of every single IFoo
function, I can do something like:
struct Fox : public IFooHelper<Fox>
{
template <class T> void onGeneric(T& t) { //do something general }
void onD(D& d) { //special behavior only for a type D }
};
This has worked fantastically well but now I am implementing a listener for which I want some common behavior, and then update a counter, say, of which type of call it was. In other words, assuming I only have types A,B,C
as above, my listener would be:
struct Ugly : public IFooHelper<Ugly>
{
void onA(A& a) { //8 lines of common code; //update some counter for type A objs; }
void onB(B& b) { //8 lines of common code; //update some counter for type B objs; }
void onC(C& c) { //8 lines of common code; //update some counter for type C objs; }
};
In here, the calls have to be very fast (so no lookups) and ideally I would be able to exploit the IFooHelper
to hoist the common behavior into the template method, and then somehow still be able to distinguish the types. I was thinking something like a template specialized struct with offsets into a static cons char* array..or with values themselves which are char* depending on T
..is there a better way?
Upvotes: 4
Views: 201
Reputation: 56863
Not sure if I fully understand what you are looking for, but I'll give it a shot. As a first step, consider this:
struct NotSoUgly : public IFooHelper<NotSoUgly>
{
void updateCounter(A& a) { //update some counter for type A objs; }
void updateCounter(B& b) { //update some counter for type B objs; }
void updateCounter(C& c) { //update some counter for type C objs; }
template <class T> void onGeneric(T& t) {
//8 lines of common code;
updateCounter(t);
}
};
Further improvements are possible if you'd show us the content of the updateCounter()
methods to we could come up with a single generic implementation for that as well, but without seeing the code, it's hard to guess.
Upvotes: 1