У меня есть вопросы с приведенным ниже фрагментом кода, не уверен, правильно ли я понимаю коды.
template <typename R, typename... Args>
class RunnableAdapter<R(*)(Args...)> {
public:
typedef R (RunType)(Args...);
explicit RunnableAdapter(R(*function)(Args...))
: function_(function) {
}
R Run(Arg... args) {
return function_(args...);
}
private:
R (*function_)(Args...);
};
<R(*)(Args...)>
такое «тип указателя на функцию» и пробел между R и (*) не обязательно требуется?
и что может быть инстанцирование RunnableAdapter?
Я предполагаю, что это как ниже.
void myFunction(int i){ // };
RunnableAdfapter<(void)(*)(int)> ra(MyFunction);
ra.Run(1); //which calls MyFunction(1)
Сначала предоставленный вами код содержит ошибки и даже не компилируется. Чтобы ответить на вопросы:
Вы можете объявить свой класс, как это
template <typename T>
class RunnableAdapter;
template <typename R, typename... Args>
class RunnableAdapter<R(*)(Args...)> { ... }
И создать его экземпляр
RunnableAdapter<void(*)(int)> ra(&myFunction);
Но вы могли бы упростить это (вот полный рабочий пример)
#include <iostream>
#include <string>
template <typename T>
class RunnableAdapter;
template <typename R, typename... Args>
class RunnableAdapter<R (Args...)> {
public:
explicit RunnableAdapter(R(*function)(Args...))
: function_(function) {
}
R Run(Args... args) {
return function_(args...);
}
private:
R (*function_)(Args...);
};
void myFunction(int i){ std::cout << i << std::endl; }
int main()
{
RunnableAdapter<void(int)> ra(&myFunction);
ra.Run(1);
}
Это позволило бы создавать экземпляры с помощью сигнатурных выражений, таких как void(int)
,
Это выглядит лучше, не нужно (*)
,
Также вот еще один способ сделать это без специализации класса, как это.
Результат тот же, но объявление класса и создание экземпляра немного отличаются.
#include <iostream>
#include <string>
template <typename R, typename... Args>
class RunnableAdapter {
public:
explicit RunnableAdapter(R(*function)(Args...))
: function_(function) {
}
R Run(Args... args) {
return function_(args...);
}
private:
R (*function_)(Args...);
};
void myFunction(int i){ std::cout << i << std::endl; }
int main()
{
RunnableAdapter<void, int> ra(&myFunction);
ra.Run(1);
}
РЕДАКТИРОВАТЬ
Как предложил @ Jarod42, лучше сделать Run
как это
template<typename... Ts>
R Run(Ts&&... args) {
return function_(std::forward<Ts...>(args)...);
}