Project Euler 2(1)

http://projecteuler.net/index.php?section=problems&id=2


Haskellならこう。

fib = 1:2:[ a + b | (a, b) <- zip fib (tail fib) ]
main = print (sum (filter even (takeWhile (<= 4 * 10^6) fib)))

filterと同様にtakewhileを作る。

template<typename T, typename U, typename V>
class takewhile {
    T   pred;
    U   obj;
    
public:
    takewhile(T p, U o) : pred(p), obj(o) { }
    
    V next() {
        decltype(obj.next())    v = obj.next();
        if(pred(v))
            return v;
        else
            throw(1);
    }
};

そうすると、

#include <iostream>

using namespace std;

const int   N = (int)4e6;

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

// 中略

int main() {
    struct f {
        bool operator ()(int n) const {
            return n <= N;
        }
    };
    
    struct even {
        bool operator ()(int n) const {
            return n % 2 == 0;
        }
    };
    
    cout << sum(filter<struct even,takewhile<struct f,fib,int>,int>(
                even(), takewhile<struct f,fib,int>(f(), fib()))) << endl;
}

ダメだこりゃ。
継承を使えばいいのだろうけど。