如何解决如何绕过C ++无法使用lambda匹配模板中的函数类型
如果您具有以下用于过滤列表的模板:
template <typename T>
inline std::list<T> list_filter(std::list<T> const& a,bool (f)(T)) {
std::list<T> output;
std::copy_if(a.begin(),a.end(),std::back_inserter(output),f);
return output;
}
然后尝试使用内部的lambda进行调用,例如:
std::list<int> lst = {1,2,3,4,5};
auto filtered = list_filter(lst,[](int el) -> bool { return (el % 2 == 0); });
它将与no matching function for call to list_filter(...,std::__cxx11::list<int>)::<lambda(int)>)'
一起产生错误。
有没有办法在不将lambda提取到单独函数中的情况下绕过该限制?为什么C ++不允许这种明显的模式?
解决方法
template argument deduction中将不考虑隐式转换(从没有捕获列表的lambda到函数指针),这无法在第二个函数参数上推导出模板参数T
。
类型推导不考虑隐式转换(上面列出的类型调整除外):这是overload resolution的工作,以后会发生。
您可以通过static_cast
或operator+
将lambda转换为函数指针。例如
auto filtered = list_filter(lst,+[](int el) -> bool { return (el % 2 == 0); });
或使用std::type_identity
(自C ++ 20起)从推论中排除第二个函数参数。例如
template <typename T>
inline std::list<T> list_filter(std::list<T> const& a,bool (f)(std::type_identity_t<T>)) {
...
}
顺便说一句,如果您的编译器不支持C ++ 20,则可以轻松制作自己的type_identity
。
带有捕获的Lambda与函数的指针不兼容(这是参数f
的含义)。
对于可调用对象,我建议您从标准库本身获取提示:对整个可调用对象使用模板参数:
template <typename T,typename F>
inline std::list<T> list_filter(std::list<T> const& a,F f) {
std::list<T> output;
std::copy_if(a.begin(),a.end(),std::back_inserter(output),f);
return output;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。