Make your Event<>
classes inherit from a common parent, say EventInterface
. The EventInterface
would be an abstract class that defines the interface to all events.
class EventInterface
{
public:
virtual void tweak ( int t ) = 0;
virtual void twiddle( int t ) = 0;
virtual void frob ( int f ) = 0;
virtual ~EventInterface() {};
};
template <typename Arg_Type> struct Event : public EventInterface {
};
Then make your vector a std::vector<EventInterface *>
or the like.
From a maintenance standpoint, it's not really that bad, because all the common interface class does is define a common interface for all events to adhere to. And if you did want to add new, non-template event classes, you could.
The downside is that you can't make ArgType
part of the common interface. However, that makes a certain amount of sense: How else would you be able to legally invoke an arbitrary method on an Event*
if you didn't know the types of the arguments?
Now you could require that all Arg_Type
be subclasses of some common EventArgument
class, and define your interface in terms of that. The template would still buy you something. It all depends on how you want to define your event interface.
Working example:
class EventArgument
{
public:
virtual int getId () = 0;
virtual ~EventArgument() { };
};
class EventInterface
{
public:
virtual void tweak ( int t ) = 0;
virtual void twiddle( int t ) = 0;
virtual void frob ( int f ) = 0;
virtual EventArgument& getArg() = 0;
virtual ~EventInterface() {};
};
class fredArg : public EventArgument
{
public:
virtual int getId() { return 1; }
~fredArg() { };
};
class barneyArg : public EventArgument
{
public:
virtual int getId() { return 2; }
~barneyArg() { };
};
template <typename Arg_Type>
struct Event : public EventInterface
{
Arg_Type arg;
Event() { };
virtual void tweak ( int t ) { };
virtual void twiddle( int t ) { };
virtual void frob ( int f ) { };
virtual EventArgument& getArg()
{
return arg;
}
};
#include <vector>
#include <iostream>
std::vector<EventInterface*> events;
int main()
{
events.push_back( new Event<fredArg>( ) );
events.push_back( new Event<barneyArg>( ) );
std::cout << events[0]->getArg().getId() << std::endl;
std::cout << events[1]->getArg().getId() << std::endl;
}
This prints 1
and 2
as you would expect.