Passing a function template as argument to another function template is always a bit tricky. Typically one has to resort to creating a lambda object that goes and calls the original function.
Example
template <typename It>
void f(It, It) {}
void g(std::vector<int>::iterator, std::vector<int>::iterator) {}
template <typename C, typename F>
void callA(C&& c, F callable) {
return callable(std::begin(c), std::end(c));
}
Problem
If I have a std::vector<int> c, I cannot just pass f along to callA because f is a template and not a function:
callA(c, f); // f has an unresolved overloaded function type and cannot be deduced
callA(c, std::distance); // same problem
callA(c, g); // works because g is a proper function, not a template
callA(c, [](auto a, auto b) {return f(a,b);}); // works again
Even if we help deduce the type of the callable:
template <typename C, template <typename> typename F,
typename T = std::decay_t<decltype(std::begin(std::declval<C>()))>>
auto callB(C&& c, F<T> callable) {
return callable(std::begin(c), std::end(c));
}
this fails to compile.
Question
Is there a way to force C++ to deduce the function's type directly without resorting to a lambda function or type-erasure like std::function? Effectively, (how) can I turn a function template into a first-class citizen? That is, have its type deduced.
I'm willing to go to some lengths when defining the higher-order function (see callB versus callA), but not when calling it.
You can change the parameter type to function pointer, which could be converted from function template (with template argument deduced). E.g.
Then
LIVE