Я бы предположил, что FooProcessor может обрабатывать только Foo, а BarProcessor может обрабатывать только Bar, но другие типы могут иметь более одного класса процессоров. Таким образом, вы можете сделать это навязчиво:
class FooProcessor
{
public:
typedef Foo value_type;
};
class BarProcessor
{
public:
typedef Bar value_type;
};
Вы можете использовать полиморфизм:
template< typename T >
class Processor
{
public:
typedef T value_type;
virtual ~Processor() {}
virtual void process( value_type * ) = 0;
};
class FooProcessor : public Processor<Foo>
{
// implement process
};
Вы можете использовать класс адаптера, как у Мэтта Филлипса, но в обратном порядке, поэтому он принимает класс процесса в качестве параметра шаблона:
template<typename T>
class Spec
{
};
template<> class Spec<FooProcessor>
{
typedef Foo type;
};
template<> class Spec<Bar>
{
typedef BarProcessor type;
};
При навязчивой типизации и наборе адаптера Spec ваш шаблон ProcessEvent будет принимать тип процессора в качестве параметра и извлекать другой, используя value_type или type.
При полиморфизме ваше ProcessEvent будет принимать тип объекта в качестве параметра (Foo или Bar) и будет передаваться процессору, производному от Processor или Processor, для обработки событий.
Если существует огромное количество событий для обработки, и они всегда обрабатывают их одним и тем же объектом, последний метод, конечно, будет несколько менее эффективным, так как он обрабатывает через v-таблицу. Частично это зависит от того, сколько времени они занимают на обработку и может ли функция, которая это делает, быть встроенной.