cGeneratorクラスを作って、next()で値を返すクラスはこれを継承することにする。
template<typename T> class cGenerator { public: virtual ~cGenerator() { } virtual T next() = 0; };
本当はポインタなんか使いたくない。いちいちdeleteしなければならないのが嫌。だから即行でdeleteする。問題ありならあとで考える。
#include <iostream> using namespace std; const int N = 1000; template<typename T> class cGenerator { public: virtual ~cGenerator() { } virtual T next() = 0; }; template<typename T = int> class range : public cGenerator<T> { T current; T end; T delta; public: range(T b, T e, T d = 1) : current(b), end(e), delta(d) { } range(T e) : end(e) { current = 0; delta = d; } range() { current = end = delta = 0; } ~range() { } T next() { if(current < end) { T v = current; current += 1; return v; } else { throw(1); } } }; template<typename T> class filter : public cGenerator<T>{ bool (* pred)(T); cGenerator<T> *obj; public: filter(bool (* p)(T), cGenerator<T> *o) : pred(p), obj(o) { } ~filter() { delete obj; } T next() { T v; do { v = obj->next(); } while(!pred(v)); return v; } }; template<typename T> T sum(cGenerator<T> *o) { T s = 0; try { while(true) { s += o->next(); } } catch(int e) { delete o; return s; } }; bool div35(int n) { return n % 3 == 0 || n % 5 == 0; } int main() { cout << sum(new filter<int>(div35, new range<>(1, N))) << endl; }
newとあとやっぱり型指定しなければならないのがみっともないが。