我正在使用C 11中提供的新的匿名函数来编写一个通用的折叠函数,这里是我所拥有的:
template<typename T> T foldl(std::function<T(T,T)> f,T initial,std::vector<T> items) { T accum = initial; for(typename std::vector<T>::iterator it = items.begin(); it != items.end(); ++it) { accum = f(accum,(*it)); } return accum; }
以下尝试使用它:
std::vector<int> arr; arr.assign(8,2); foldl([] (int x,int y) -> int { return x * y; },1,arr);
导致错误:
main.cpp:44:61: error: no matching function for call to 'foldl(main(int,char**)::<lambda(int,int)>,int,std::vector<int>&)' main.cpp:44:61: note: candidate is: main.cpp:20:3: note: template<class T> T foldl(std::function<T(T,T)>,T,std::vector<T>) main.cpp:20:3: note: template argument deduction/substitution Failed: main.cpp:44:61: note: 'main(int,int)>' is not derived from 'std::function<T(T,T)>'
解决方法
你的代码不是很通用.没有必要要求一个函数,矢量或任何类型的东西.一般来说,在C中,函数将在参数列表的末尾(对于lambdas尤其重要,因为它们可能很大).
所以这样做会更好(即:更标准)
template<typename Range,typename Accum> typename Range::value_type foldl(const Range &items,const typename Range::value_type &initial,Accum f) { typename Range::value_type accum = initial; for(const auto &val : items) { accum = f(accum,val); } return accum; }
或者你可以只是use std::accumulate
这是完全相同的事情.