Шаблонный указатель на функцию? - PullRequest
1 голос
/ 14 октября 2010

Я хочу сделать что-то вроде этого: я хочу, чтобы пользователь предоставлял тип возвращаемого значения и аргумент (всегда будет только один), затем я хочу, чтобы пользователь мог предоставить указатель на функцию, которая соответствует этому критерию,Я буду использовать это, чтобы создать синхронизированное событие.Проблема здесь в том, что обычно с шаблонами вы должны предоставить T и создать новый экземпляр класса, однако в этом случае он мне нужен как среда выполнения.Например:

TimeEvent *explode  = new TimeEvent(int (the return type),data (the argument), explodeFunc (the function pointer);

Это создаст и установит указатель на функцию.Затем вызывающая сторона просто взрывает .call (), чтобы вызвать его.Как я мог достичь чего-то подобного?

Спасибо

1 Ответ

3 голосов
/ 14 октября 2010

Ну boost.function + boost.bind - это то, что вы можете использовать для этого:

int explodeFunc( std::string const & someString ) {
     std::cout << someString << " exploded" << std::endl;
     return 1;
}

и позже ...

boost::function< int() > timeEvent = boost::bind(explodeFunc, "The world"); 
int retVal = timeEvent();

Но я не уверен, что это то, что вы ищете

Вот простая версия без наддува:

#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;
}

Я надеюсь, что вы поняли идею и сможете сделать ее соответствующей вашим потребностям.

НТН

Редактировать: Обновлено с шаблонным типом возврата. * Сделано create_time_event немного более удобным для пользователя

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...