Здравствуйте!
Подниму старую тему. Случайно нагуглил по ключевому слову "мультиметоды". Позвольте попиариться.
Ваша задача решается очень просто с помощью мультиметода.
Пример упростил для понимания и чтобы скомпилировать и проверить.
#include <iostream>
#include <functional>
#include <mml/generation/make_multimethod.hpp>
struct BasePacket
{
virtual void F() const = 0; // большой список параметров
};
struct PingPacket: public BasePacket
{
virtual void F() const
{
}
int int_field;
};
struct PongPacket: public BasePacket
{
virtual void F() const // лишние параметры
{
}
float float_field;
};
struct Connection
{
void handle_packet_base(BasePacket *packet)
{
std::cout << typeid(BasePacket).name();
}
void handle_packet_ping(PingPacket *packet)
{
std::cout << typeid(PingPacket).name();
}
void handle_packet_pong(PongPacket *packet)
{
std::cout << typeid(PongPacket).name();
}
void main_cycle()
{
// p может указывать на любой объект подкласса BasePacket или самого BasePacket
BasePacket *p = new PingPacket; // receive_packet()
mml::make_multimethod(
std::mem_fun(&Connection::handle_packet_base)
, std::mem_fun(&Connection::handle_packet_ping)
, std::mem_fun(&Connection::handle_packet_pong)
) // создает функциональный объект
(this, p); // вызывает его
// если доступно ключевое слово auto, то можно сохранить мультиметод в переменную auto mm = make_multimethod(...),
// иначе, можно сохранить, обернув в boost::function<void(Connection*, BasePacket*)> mm = make_multimethod(...),
// или передать в шаблонную функцию, которая сама выведет тип мультиметода
// как своего шаблонного параметра, например: process_packet(make_multimethod(...), this, p)
}
};
Единственное, что здесь важно — это создать мультиметод.
Для этого нужно заинклудить: <mml/generation/make_multimethod.hpp> и вызвать mml::make_multimethod.
Хотя в этом примере мультиметод вырожденный (он диспетчеризует по одному полиморфному аргументу, а не по множеству), тем не менее его можно использовать как внешнюю полиморфную функцию над одним аргументом (connection здесь не полиморфен и в диспетчеризации не участвует).
В этой библиотеке можно смешивать полиморфные и неполиморфные аргументы. Диспетчеризация в рантайме будет работать только на полиморфных аргументах (будет вычисляться их реальный динамический подтип).
Библиотека находится
тут.
Описание с примерами и теорией можно почитать
тут.
Надеюсь, библиотека будет полезна.