What I am trying to accomplish is the following:
// or any templated function
template <typename... Args>
void function(Args... args) {}
// wrapper
void launch(???) { ??? }
int main()
{
// first option
launch(function, 1, 2, 3, 4);
// second option
launch<function>(1, 2, 3, 4);
}
As far as I can tell, the first option is impossibile since I would have to pass the specialized template function (which I'm trying to avoid).
For the second option I don't know if it's possible, I came up with the following not working implementation:
template <template <typename...> class Function, typename... Args>
void launch(Args... args)
{
Function<Args...>(args...);
}
which ends up giving me:
main.cpp:18:5: error: no matching function for call to 'launch'
launch<function>(1, 2, 3, 4);
^~~~~~~~~~~~~~~~
main.cpp:9:6: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'Function'
void launch(Args... args)
^
1 error generated.
So, is something like this even possible?
You basically cannot do anything with function templates except call them (and let arguments get deduced) or instantiate them (by manually specifying template arguments).
I believe there are also niche situations where template arguments may be deduced and a specific instantiation chosen without an actual call, but they don't help here AMA's answer shows how to do that!
Generic lambdas may or may not help you solve your problem, but you need one such forwarding lambda per function template you want to make "passable":
#include <functional>
// or any templated function
template <typename Arg1, typename Arg2>
void function(Arg1 arg1, Arg2 arg2) {}
int main()
{
auto wrapper = [](auto arg1, auto arg2) {
return function(arg1, arg2);
};
std::invoke(wrapper, 1, 2);
}
Demo
(Perfect-forwarding to a variadic function with a variadic lambda would be more complicated.)
So you might as well write function templates in the form of functor structs in the first place, or in the form of lambdas returned from non-template functions.
How about:
template <typename ... Args>
void launch(void(*func)(Args...), Args&&... args) {
func(std::forward<Args>(args)...);
}
calling launch:
launch(function, 1, 2, 3, 4);
Live example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With