Обновление 2: Boost.Lambda делает из этого кусок пирога:
// headers
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
using namespace boost::lambda;
// ...
cout << accumulate(dv.begin(), dv.end(),
0,
_1 += bind(&strange::value, _2)) //strange defined below
<< endl;
Обновление: Это меня давно беспокоило. Я не могу просто заставить любой алгоритм STL работать прилично. Итак, я свернул свой собственный:
// include whatever ...
using namespace std;
// custom accumulator that computes a result of the
// form: result += object.method();
// all other members same as that of std::accumulate
template <class I, class V, class Fn1, class Fn2>
V accumulate2(I first, I last, V val, Fn1 op, Fn2 memfn) {
for (; first != last; ++first)
val = op(val, memfn(*first));
return val;
}
struct strange {
strange(int a, int b) : _a(a), _b(b) {}
int value() { return _a + 10 * _b; }
int _a, _b;
};
int main() {
std::vector<strange> dv;
dv.push_back(strange(1, 3));
dv.push_back(strange(4, 6));
dv.push_back(strange(20, -11));
cout << accumulate2(dv.begin(), dv.end(),
0, std::plus<int>(),
mem_fun_ref(&strange::value)) << endl;
}
Конечно, оригинальное решение остается в силе:
Самый простой - реализовать operator+
. В этом случае:
double operator+(double v, Object const& x) {
return v + x.a_;
}
и сделайте его другом Object
или участником (посмотрите, почему вы предпочитаете одно другому):
class Object
{
//...
friend double operator+(double v, Object const& x);
и все готово:
result = accumulate(collection.begin(), collection.end(), 0.0);
Мой предыдущий подход не работает, потому что нам нужен binary_function
.
STD :: накапливать Руководство.