Pythonのitertoolsを使ったような書き方がC++でもできるようにライブラリを作っていきます。具体的には、例えば、1から10の和を求めるときにこう書けるようにします。
cout << sum(range(1, 11)) << endl;
Pythonのxrangeやtakewhileをクラスを使って実現します。これらは、cIterable
template<typename T> class cIterable { public: virtual ~cIterable() { } virtual bool exists_next() = 0; virtual T value() const = 0; };
そして、これを関数で包んで型推論させてポインタを返します。再帰で使うときにポインタだと書きやすいからです(たぶん)。しかしメモリの管理はしたくないので、shared_ptrを使います。したがって、関数はshared_ptr
まず、Pythonのxrangeをrangeという関数名で実現しました。
#include <iostream> #include <memory> using namespace std; template<typename T> class cIterable { public: virtual ~cIterable() { } virtual bool exists_next() = 0; virtual T value() const = 0; }; class cRange : public cIterable<int> { int current; int end; int delta; bool first; public: cRange(int e) : current(0), end(e), delta(1), first(true) { } cRange(int b, int e) : current(b), end(e), delta(1), first(true) { } cRange(int b, int e, int d) : current(b), end(e), delta(d), first(true) { } ~cRange() { cout << "cRange::~cRange" << endl; } bool exists_next() { if(first) first = false; else current += delta; return delta > 0 ? current < end : current > end; } int value() const { return current; } }; shared_ptr<cIterable<int>> range(int e) { return shared_ptr<cIterable<int>>(new cRange(e)); } shared_ptr<cIterable<int>> range(int b, int e) { return shared_ptr<cIterable<int>>(new cRange(b, e)); } shared_ptr<cIterable<int>> range(int b, int e, int d) { return shared_ptr<cIterable<int>>(new cRange(b, e, d)); } template<typename T> ostream operator <<(ostream& os, const shared_ptr<cIterable<T>>& g) { if(g->exists_next()) { os << g->value(); while(g->exists_next()) os << " " << g->value(); } return os; } int main() { auto r = range(1, 11); cout << r << endl; }