Project Euler 2(2)

takewhileもfilterと同じように定義する。

#include <iostream>

using namespace std;

const int   N = (int)4e6;

template<typename T>
class cGenerator {
public:
    virtual ~cGenerator() { }
    virtual T next() = 0;
};

template<typename T>
class takewhile : public cGenerator<T>{
    bool (* pred)(T);
    cGenerator<T>   *obj;
    
public:
    takewhile(bool (* p)(T), cGenerator<T> *o) : pred(p), obj(o) { }
    ~takewhile() {
        delete obj;
    }
    T next() {
        T   v = obj->next();
        if(pred(v))
            return v;
        else
            throw(1);
    }
};

// 中略

class fib : public cGenerator<int> {
    int     a;
    int     b;
    
public:
    fib() {
        a = 0;
        b = 1;
    }
    int next() {
        int tmp = b;
        b = a + b;
        a = tmp;
        return b;
    }
};

bool even(int n) { return n % 2 == 0; }
bool f(int n) { return n <= N; }

int main() {
    cout << sum(new filter<int>(even,
            (new takewhile<int>(f, new fib())))) << endl;
}