我有以下模板
template<typename T,typename U> std::vector<U> map(const std::vector<T> &v,std::function<U(const T&)> f) { std::vector<U> res; res.reserve(v.size()); std::transform(std::begin(v),std::end(v),std::end(res),f); return res; }
当我在我的代码中使用它,我有指定模板参数.为什么编译器不能为我推断这个?如何更改我的模板定义以使其工作?
vector<int> numbers = { 1,3,5 }; // vector<string> strings = map(numbers,[] (int x) { return string(x,'X'); }); vector<string> strings = map<int,string>(numbers,'X'); });
可运行代码:http://ideone.com/FjGnxd
这个问题的原始代码来自于:The std::transform-like function that returns transformed container
解决方法
你的函数需要一个std :: function参数,但是你用lambda表达式来调用它.两者不一样.一个lambda可以转换成std :: function,但是模板参数的扣除需要精确的匹配,不考虑用户定义的转换.因此扣除失败.
如果您实际将std ::函数传递给map(),则扣除工作正常.
std::function<string(int const&)> fn = [] (int x) { return string(x,'X'); }; vector<string> strings = map(numbers,fn);
避免必须指定模板参数的一种可能的解决方法是修改函数以接受任何类型的可调用,而不是std :: function对象.
template<typename T,typename Func> std::vector<typename std::result_of<Func(T)>::type> map(const std::vector<T> &v,Func f) { // ... }
同一个想法的另一个版本,使用decltype和declare而不是result_of
template<typename T,typename Func> std::vector<decltype(std::declval<Func>()(std::declval<T>()))> map(const std::vector<T> &v,Func f) { // ... }
最后,使用尾随返回类型
template<typename T,typename Func> auto map(const std::vector<T> &v,Func f) -> std::vector<decltype(f(v[0]))> { // ... }
原文地址:https://www.jb51.cc/c/114852.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。