In C++ we can pretty easily define template function arguments as seen in this question. However, this only allows functions with a defined parameter list and return value.
We can make those types template parameters like this:
template<typename R, typename P, R(*Func)(P)>
R proxy_func(P arg)
{
// do some stuff...
R&& res{ Func(std::forward(arg)) };
// do some more stuff...
return res;
}
However, here we are still limited to a fixed number of parameters.
An attempt like the following won't compile (at least on MSVC 19.24.28315), because "template parameter 'Func' cannot be used because it follows a template parameter pack and cannot be deduced from the function parameters of 'proxy_func'".
template<typename R, typename... P, R(*Func)(P...)>
R proxy_func(P... args)
{
// do some stuff...
R&& res{ Func(std::forward(args)...) };
// do some more stuff...
return res;
}
So what are the options for allowing an arbitrary function as template argument and - just as importantly - allow its parameters to be used as the parameters for, say, the function template it's used in (like in proxy_func
above)? Ideally, I would be able to call proxy_func
with just any function as (ideally single) template argument Func
and be able to apply its (proxy_func
's) arguments to Func
.
Edit: I am particularly interested in having a function-instance as template argument (e. g. to allow template instantiations of proxy_func
to apply compile-time optimisations based on individual Func
s).
In some sense, the Q&A you link is the complicated way. The simple way is:
template <typename F>
void foo(F f) {
f(); // call the function
}
In your case the return value can be deduced and the argument types can be deduced from the parameters to foo
. Note that they need not necessarily match exactly the argument types of f
as long as f
can be called with them:
template <typename F,typename ... Args>
auto foo( F f, Args ... args) {
return f(args...); // call the function
}
For the sake of brevity I ommitted forwarding and storing the result of the call in a temporary, but the answer still applies.
In case you want to have the function itself, not its type as template parameter (sorry I missed that part first) this still works:
template <auto f,typename ... Args>
auto foo(Args ... args) {
return f(args...); // call the function
}
However, this won't work in case f
is a lambda. See here for details: https://en.cppreference.com/w/cpp/language/template_parameters#Non-type_template_parameter