Reputation: 54113
I want to do something like this: I want the user to provide a return type and an argument (there will always only be one) then I want the user to be able to provide the pointer of a function that matches this criteria. I will be using this to create a timed event. The issue here is that usually with templates you must provide T and make a new class instance, however in this case I need it kind of a runtime. ex:
TimeEvent *explode = new TimeEvent(int (the return type),data (the argument), explodeFunc (the function pointer);
This would then create and set the function pointer. Then the caller simply does explode.call() to call it. How could I achieve something like this?
Thanks
Upvotes: 1
Views: 282
Reputation: 2819
Well boost.function + boost.bind is something you can use for this:
int explodeFunc( std::string const & someString ) {
std::cout << someString << " exploded" << std::endl;
return 1;
}
and later...
boost::function< int() > timeEvent = boost::bind(explodeFunc, "The world");
int retVal = timeEvent();
But I am not sure if this is what you are looking for
Here a simple version without boost:
#include <iostream>
#include <string>
template< typename R >
struct TimeEvent {
virtual ~TimeEvent(){}
virtual R call() = 0;
};
template< typename R, typename ParamType >
struct TimeEventT : TimeEvent<R> {
typedef R (*callback_type)( ParamType const & );
typedef ParamType param_type;
TimeEventT( param_type const & param, callback_type cb )
: TimeEvent<R>()
, callback_( cb )
, param_( param )
{}
R call() {
return callback_( param_ );
}
protected:
callback_type callback_;
param_type param_;
};
template< typename R, typename ParamType, typename ParamValueT >
TimeEvent<R> * create_time_event(
R (*cb)(ParamType const &),
ParamValueT const & param
) {
return new TimeEventT<R, ParamType>( param, cb );
}
int explodeFunc( std::string const & param ) {
std::cout << param << " exploded" << std::endl;
return 1;
}
std::string explodeFuncString( std::string const & param ) {
return param + " really exploded this time";
}
int main(){
std::string param = "The world";
TimeEvent<int> * timeEvent1 = create_time_event( explodeFunc, param );
if( timeEvent1 ) {
timeEvent1->call();
delete timeEvent1;
}
TimeEvent<std::string> * timeEvent2 = create_time_event( explodeFuncString, param );
if( timeEvent2 ) {
std::cout << timeEvent2->call() << std::endl;
delete timeEvent2;
}
return 0;
}
I hope you get the idea and can make it fit your needs.
HTH
Edit: Updated with templated return type. * Made create_time_event a bit more user friendly
Upvotes: 3