c – 编译器不推导出模板参数(map std :: vector – > std ::
发布时间:2020-12-16 05:22:14 所属栏目:百科 来源:网络整理
导读:我有以下模板 templatetypename T,typename Ustd::vectorU map(const std::vectorT v,std::functionU(const T) f) { std::vectorU res; res.reserve(v.size()); std::transform(std::begin(v),std::end(v),std::end(res),f); return res;} 当我在我的代码中
我有以下模板
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); Live demo 避免必须指定模板参数的一种可能的解决方法是修改函数以接受任何类型的可调用,而不是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]))> { // ... } Live demo (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |