Вы пытаетесь сохранить объект функции в указателе функции, но это невозможно. Вы должны хранить std::tr1::function
вместо:
#include <functional>
typedef std::tr1::function<void(FCPackage*)> FCPackageHandlerFunction;
class FCPackageHandlers{
...
void registerHandler(FCPackage::Type type, FCPackageHandlerFunction handler);
void handle(FCPackage* package);
...
QHash<FCPackage::Type, FCPackageHandlerFunction> _handlers;
};
Существует похожий класс function
в Boost, если у вас еще нет доступа к std :: tr1.
Также рассмотрите возможность использования boost::bind
и обычной функции, чтобы избежать необходимости создавать собственные функциональные объекты, такие как FCLoginHandler
:
void handle_FC_login(FCServer* server, FCPackage* package)
{
std::cout << "Received package: " << package->toString().data() << "\n";
// You can use server if you need it
}
FCServer::FCServer()
{
_handlers.registerHandle(FCPackage::Login,
std::tr1::bind(&handle_FC_login, this, _1));
}
std::tr1::bind
также доступен в Boost, и если у вас нет к нему доступа, вы всегда можете использовать std::bind2nd
.
РЕДАКТИРОВАТЬ: Поскольку вы не можете изменить тип FCPackageHandlerFunction
, лучше всего добавить еще один хеш, который хранит данные, связанные с каждым указателем функции:
typedef void (*FCPackageHandlerFunction)(FCPackage*);
class FCPackageHandlers{
...
void registerHandler(FCPackage::Type type, FCPackageHandlerFunction handler,
FCServer * func_data);
void handle(FCPackage* package);
...
QHash<FCPackage::Type, FCPackageHandlerFunction> _handlers;
QHash<FCPackageHandlerFunction, FCServer*> _handler_func_data;
};
// The server will be passed by the package handler which will
// extract it from the _handler_func_data hash
void handle_FC_login(FCServer* server, FCPackage* package)
{
std::cout << "Received package: " << package->toString().data() << "\n";
}
FCServer::FCServer(){
_handlers.registerHandle(FCPackage::Login, &handle_FC_login, this );
}
Предположительно, это то, как вам нужно реализовать FCPackageHandlers::handle
:
void FCPackageHandlers::handle(FCPackage * package)
{
// Query function
FCPackageHandlerFunction func = _handlers[package->GetType()];
// Query associated data
FCServer * server = _handler_func_data[func];
// Call handler
func(server, package);
}