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; }