bit*_*ask 5 c++ templates first-class-functions language-lawyer higher-order-functions
将函数模板作为参数传递给另一个函数模板总是有点棘手。通常,人们必须创建一个 lambda 对象来调用原始函数。
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));
}
Run Code Online (Sandbox Code Playgroud)
如果我有一个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
Run Code Online (Sandbox Code Playgroud)
即使我们帮助推断可调用的类型:
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));
}
Run Code Online (Sandbox Code Playgroud)
这无法编译。
有没有办法强制 C++ 直接推导函数的类型,而不需要借助 lambda 函数或类型擦除之类的std::function?实际上,(如何)我可以将函数模板变成一等公民?即推导其类型。
在定义高阶函数时(请callB参阅与),我愿意付出一定的努力callA,但在调用它时则不愿意。
您可以将参数类型更改为函数指针,该函数指针可以从函数模板转换(推导模板参数)。例如
template <typename C>
void callA(C&& c, void(*callable) (std::decay_t<decltype(std::begin(std::declval<C>()))>, std::decay_t<decltype(std::begin(std::declval<C>()))>)) {
return callable(std::begin(c), std::end(c));
}
Run Code Online (Sandbox Code Playgroud)
然后
std::vector<int> c;
callA(c, f); // template argument It will be deduced as std::vector<int>::iterator for f
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
161 次 |
| 最近记录: |