用了一段時間的函數式語言像erlang、mathematica,經過fold,map,filter
等高階函數來編程確有好處。c++
固然也有它的缺點。程序員
因而我寫了一個擴展類,來使得STL容器具有高階函數。 默認將結果保存到本容器。算法
template<class Collection> class FP : public Collection { public: template<typename T> FP(std::initializer_list<T> list):Collection(list) {} template<typename ...Args> explicit FP(Args... args) { Collection(args...); } explicit FP(Collection &c) : Collection(c) {} template<typename unop> FP<Collection> each(unop op) { std::for_each(this->begin(), this->end(), op); return *this; } template<typename unop> FP<Collection> map(unop op) { std::transform(this->begin(), this->end(), this->begin(), op); return *this; } template<typename unop,class ...C> FP<Collection> thread(unop op,C... c) { this->clear(); const size_t size=get_size(c...); for(int i=0;i<size;i++) this->push_back(apply_from_tuple(op,value_tuple(i,c...))); return *this; } template<typename TResult, typename F> TResult fold(const TResult &startValue, const F &f) { TResult result = startValue; auto p = this->begin(); while (p != this->end()) result = f(result, *p++); return result; } template< typename F> auto reduce(const F &f) { auto p = this->begin(); auto result=*p++; while (p != this->end()) result = f(result,*p++ ); return result; } template<typename binop> FP<Collection> zip(Collection fc, Collection sc, binop op) { std::transform(fc.begin(), fc.end(), sc.begin(), fc.begin(), op); Collection::assign(fc.begin(), fc.end()); return *this; } template<typename Condition> bool exists(Condition con) { auto exist = std::find_if(this->begin(), this->end(), con); return exist != this->end(); } template<typename Predicate> Collection filterNot(Predicate predicate) { auto returnIterator = std::remove_if(this->begin(), this->end(), predicate); this->erase(returnIterator, std::end(this)); return *this; } };
example:編程
int main() { FP<vector<int>> v1{1,2,3,4,5}; funt(v1); cout<<"list : "; for(auto p:v1) cout<<" "<<p; cout<<endl; int sum=v1.reduce([](int a,int b){return a+b;}); cout<<"sum : "<<sum<<endl; FP<vector<int>> v2=v1; cout<<"map i*i : "; v1.map([](int i){return i*i;}).each([](int i){ cout<<i<<" "; }); cout<<endl; cout<<"thread: "; v2.thread([](int a,int b){return a-b;},v1,v2).each([](int i){ cout<<i<<" "; }); cout<<endl; //對map容器操做 FP<std::map<int,float>> m; for(auto i:v2) m[i]=i*i; print(m); m.each([](std::pair<const int,float>& it){ it.second+=0.2;}); cout<<"操做後"<<endl; print(m); return 0; }
在C++中使用函數式還要考慮內存分配問題。畢竟語言支持不太好,在正式環境下仍是避免使用的好。使用標準的STL transform 很大程度上也能夠實現一些功能。app
這個操做通常的函數式語言是沒有的,這個是從mathematica上學到的。它將多個大小相同的集合用函數op組合在一塊兒,相似與ZIP操做,但zip只能處理2組容器,而thread能夠處理任意個。函數
c++函數式post