I am implementing a template for a wrapper, as in :
- C++ function call wrapper with function as template argument
- Wrap a function pointer in C++ with variadic template
The wrapper taken from the links above is :
template<typename Fn, Fn fn, typename... Args>
typename std::result_of<Fn(Args...)>::type
wrapper(Args&&... args) {
return fn(std::forward<Args>(args)...);
}
#define WRAPPER(FUNC) wrapper<decltype(&FUNC), &FUNC>
Given two functions foo and foo2 :
int foo (int a) {return a};
template <class T>
T foo2(T a)
{
return a;
}
WRAPPER(foo)(4) /*Works*/
WRAPPER(foo2)(4) /*Doesn't work*/
I understand that it is because decltype(&FUNC)
cannot be determined unless the template function is given its arguments' types. The thing is that the information is there at compile time, ie. foo2 is called with an int, so is of type int (int) etc. etc. Isn't there some way to express things so that the type of the function is determined with the type of the arguments ?
Simplification
I removed the template call in the code above to isolate the wrapper part and thus have access to both the function and its arguments on the same "level" :
template<class F, typename... Args>
typename std::result_of<F(Args...)>::type wrapper2(F&& fn, Args&&... args)
{
return fn(std::forward<Args>(args)...);
}
wrapper2(foo, 4) /*works*/
wrapper2(foo2, 4) /* the instance of foo2 to create cannot be determined */
The wrapper should ideally be able to create the correct instance of foo2
given the types of the list of arguments.