Можно ли связать функции с производными параметрами? И если как? Я хотел бы иметь возможность хранить функциональные точки для различных функций, которые имеют одинаковую сигнатуру, а именно, они берут класс с входными данными и возвращают класс с выходными значениями. Но разные функции требуют и предоставляют разные параметры, поэтому я пытаюсь зарегистрировать функции, которые принимают производные классы сообщений.
Следующий код работает частично. Я могу зарегистрировать функцию MathService::blank и позже вызвать ее. Но я не могу добавить MathService::add.
Ошибка, которую я получаю:
main.cpp:70:93: ошибка: преобразование из 'std::_Bind_helper&)(RequestMessage&, ReplyMessage&), MathService&, const std::_Placeholder‹1>&, const std::_Placeholder‹2>&>::type { aka std::_Bind(MathService*, std::_Placeholder‹1>, std::_Placeholder‹2>)>}' в нескалярный тип 'Service::serviceFunction_t {aka std::function}' запрошенный serviceFunction_t fn = bind( methodPtr, objectPtr, placeholders::_1, placeholders::_2 );
#include <functional>
#include <unordered_map>
#include <iostream>
using namespace std;
// base class for messages passed around
class BaseMessage
{
public:
virtual void print()
{
cout << "BaseMessage\n";
}
};
// request message with data passed to the service
class RequestMessage : public BaseMessage
{
public:
RequestMessage( int a_, int b_ ) : a( a_ ), b( b_ ) {}
int a;
int b;
void print()
{
cout << "RequestMessage a=" << a << " b=" << b << endl;
}
};
// reply message with return values from the service
class ReplyMessage : public BaseMessage
{
public:
ReplyMessage() : sum( 0 ) {}
int sum;
void print()
{
cout << "ReplyMessage sum=" << sum << endl;
}
};
// Example service provider
class MathService
{
public:
void blank( BaseMessage& request, BaseMessage& reply )
{
request.print();
reply.print();
}
void add( RequestMessage& request, ReplyMessage& reply )
{
reply.sum = request.a + request.b;
}
};
// Class manages services, register a new service with addService and call the service by name using call
class Service
{
public:
using serviceFunction_t = function<void ( BaseMessage&, BaseMessage& )>;
template<class Method, class Obj>
void addService( string name, Method methodPtr, Obj objectPtr )
{
serviceFunction_t fn = bind( methodPtr, objectPtr, placeholders::_1, placeholders::_2 );
pair< string, serviceFunction_t> entry( name, fn );
mFunctionMap.insert( entry );
}
void call( const string& name, BaseMessage& request, BaseMessage& reply )
{
std::unordered_map<string, serviceFunction_t>::const_iterator it;
it = mFunctionMap.find( name );
if( it == mFunctionMap.end() ) {
std::cout << "service not found: " << name << endl;
return;
}
serviceFunction_t fn = it->second;
fn( request, reply );
}
private:
unordered_map<string, serviceFunction_t> mFunctionMap;
};
int main()
{
MathService math;
Service service;
// can add a service with BaseMessages
service.addService( "blank", &MathService::blank, &math );
//*****************************************************
// PROBLEM is here !!
// can not add a service with derived message types, this causes the bind call to fail in Service::addService()
service.addService( "add", &MathService::add, &math );
//*****************************************************
// this works
BaseMessage req1, rep1;
service.call( "blank", req1, rep1 );
// so does this
RequestMessage req2( 1, 2 );
ReplyMessage rep2;
service.call( "blank", req2, rep2 );
// this service is not registered
service.call( "add", req2, rep2 );
}
do
— зарезервированное ключевое слово - person quantdev   schedule 07.08.2014std::placeholders_1
наstd::placeholders::_1
- person usta   schedule 07.08.2014