您是否考虑过 std::function 作为您的包装器?与 std::bind 或 lambdas 结合使用,它可能可以完成您需要的一切。例如,
#include <unordered_map>
#include <functional>
#include <exception>
#include <memory>
#include <string>
#include <iostream>
class Evaluator
{
public:
virtual ~Evaluator() {}
virtual double Evaluate( const double*, int ) = 0;
// ...
};
class Registry
{
public:
typedef std::function<double(const double*, int)> Fn; // For easier reading
class NameNotFoundException : public std::exception {};
void Register( const std::string& name, const Fn& fn )
{
_regMap[ name ] = fn;
}
void Call( const std::string& name, const double* const data, const int size )
{
auto it = _regMap.find( name );
if( it == _regMap.end() )
{
throw NameNotFoundException();
}
it->second( data, size ); // Call fn
}
private:
std::unordered_map<std::string, Fn> _regMap;
};
class EvaluatorImpl : public Evaluator
{
public:
double Evaluate( const double* const data, const int size )
{ /*...*/
for( int n=0; n < size; ++n )
std::cout << data[n] << '\n';
return 0;
}
// ...
};
int main()
{
std::shared_ptr<Evaluator> eval( new EvaluatorImpl() );
Registry reg;
// Could use a lambda here instead of std::bind
reg.Register( "Bob",
std::bind( &Evaluator::Evaluate, eval, std::placeholders::_1, std::placeholders::_2 ) );
const double data[] = { 1, 2, 3 };
int size = 3;
reg.Call( "Bob", data, size );
}