Указатель на функцию C ++ в качестве параметра шаблона

У меня есть вопросы с приведенным ниже фрагментом кода, не уверен, правильно ли я понимаю коды.

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...);
};
  1. <R(*)(Args...)> такое «тип указателя на функцию» и пробел между R и (*) не обязательно требуется?

  2. и что может быть инстанцирование RunnableAdapter?
    Я предполагаю, что это как ниже.
    void myFunction(int i){ // };
    RunnableAdfapter<(void)(*)(int)> ra(MyFunction);
    ra.Run(1); //which calls MyFunction(1)

2

Решение

Сначала предоставленный вами код содержит ошибки и даже не компилируется. Чтобы ответить на вопросы:

  1. Пробелы не нужны.
  2. См. Пример ниже

Вы можете объявить свой класс, как это

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)...);
}
1

Другие решения


По вопросам рекламы [email protected]