C++ で Ruby の inject みたいなやつを作ってみる
仕事で C++ を使うことになったので、リハビリを兼て Ruby の inject みたいな (lisp の apply みたいな) 関数を書いてみた。
#include <iostream> #include <vector> #include <functional> using namespace std; #define ARRSIZ(a) (sizeof(a)/sizeof((a)[0])) #define ARREND(a) ((a)+ARRSIZ(a)) template <class T, class R, class F> R inject(T begin, T end, R result, F func) { for (; begin != end; ++begin) result = func(result, *begin); return result; } template <class T> struct PLUS { T operator()(const T& a, const T& b) const { return a + b; } }; int main() { int src[] = {1, 2, 3, 4, 5}; vector<int> v; vector<double> w; for (int* i = src; i != ARREND(src); ++i) { v.push_back(*i); w.push_back(*i * 1.1); } cout << inject(src, ARREND(src), 0, plus<int>()) << endl; cout << inject(v.begin(), v.end(), 0, plus<int>()) << endl; cout << inject(w.begin(), w.end(), 0.0, plus<double>()) << endl; cout << inject(v.begin(), v.end(), 0, PLUS<int>()) << endl; cout << inject(w.begin(), w.end(), 0.0, PLUS<double>()) << endl; return 0; }
inject の受け取る、型 F がなんかよく分からん。
template 使うと、関数オブジェクトを関数内でちょいちょいっと書けないのかね。
struct _plus_ { int operator()(const int& a, const int& b) const { return a + b; } }; cout << inject(v.begin(), v.end(), 0, _plus_()) << endl;
上のように main() の中で struct を書くと、
warning: template argument uses local type '_plus_'
こんな感じで怒られる。めんどくさい。
今時ならラムダ式を使うといいんだろうか?
そもそも inject に相当する関数はどこかに定義されてるんじゃないのか?