将函数模板作为参数传递给另一个函数模板总是有点棘手。通常,人们必须创建一个 lambda 对象来调用原始函数。
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
如果我有一个std::vector<int> c
,我不能就这么过去f
沿着callA
因为f
是一个模板而不是一个函数:
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
即使我们帮助推断可调用的类型:
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 编译失败.
Question
有没有办法强制 C++ 直接推导函数的类型,而不需要借助 lambda 函数或类型擦除之类的std::function
?有效地,(如何)我可以将函数模板变成一等公民吗?即推导其类型。
我愿意竭尽全力defining高阶函数(参见callB
versus callA
),但不是当calling it.