At first the code you provided have some mistakes and does not even compile. To answer tou questions:
- Spaces are not necessary.
- See below example
You could declare you class like this
template <typename T>
class RunnableAdapter;
template <typename R, typename... Args>
class RunnableAdapter<R(*)(Args...)> { ... }
And instantiate it
RunnableAdapter<void(*)(int)> ra(&myFunction);
But you could simplify it (here is full working example)
#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);
}
This would allow instantiation with signature-like expressions like void(int)
.
It just looks better, no need in (*)
.
Also here is another way is to do it without class specialization, like this.
The result is the same, but class declaration and instantiation is slightly different.
#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);
}
EDIT
As @Jarod42 proposed it is better to make Run
like this
template<typename... Ts>
R Run(Ts&&... args) {
return function_(std::forward<Ts...>(args)...);
}