Project Euler 2(2)

takewhileもfilterと同様に定義する。
N以下まで値を出すときに、

const int   N = (int)4e6;
takewhile([] (int n) { return n <= N; }, fib());

これだとNが見えない。[]の中にNを書いて、

const int   N = (int)4e6;
takewhile([N] (int n) { return n <= N; }, fib());

とすると値がコピーされて使えるようになる。

// sumとfilterは省略
#include <iostream>

using namespace std;

class fib {
    int prev;
    int current;
    
public:
    fib() : prev(1), current(1) { }
    int next() {
        int v = current;
        current += prev;
        prev = v;
        return v;
    }
};

template<typename T, typename U, typename V>
class cTakeWhile {
    T&  pred;
    U&  gen;
    
public:
    cTakeWhile(T& p, U& g) : pred(p), gen(g) { }
    V next() {
        V   v = gen.next();
        if(pred(v))
            return v;
        else
            throw(1);
    }
};

template<typename T, typename U>
auto takewhile(T& pred, U& gen) -> cTakeWhile<T,U,decltype(gen.next())> {
    return cTakeWhile<T,U,decltype(gen.next())>(pred, gen);
}

int main() {
    const int   N = (int)4e6;
    
    cout << sum(filter([] (int n) { return n % 2 == 0; },
            takewhile([N] (int n) { return n <= N; }, fib()))) << endl;
}