Я всегда стараюсь включать алгоритмы STL, где только могу, а не писать ручные циклы. Однако мне трудно понять, как std::accumulate
вообще полезен. Всякий раз, когда мне нужно вычислять суммы или средние значения, я почти всегда прибегаю к ручным циклам, потому что мне трудно получить std::accumulate
, чтобы делать то, что мне нужно.
Проблема в том, что я редко когда-либо имел простой вектор целых чисел, которые нужно суммировать. Обычно я хочу суммировать массив объектов с использованием определенной переменной-члена. Да, я знаю, что есть версия std::accumulate
, которая принимает двоичную функцию, но проблема, которую я вижу, заключается в том, что этой функции нужно взять два значения типа T
, где T
- тип суммы, а не тип операндов. У меня возникли проблемы с пониманием того, как это полезно.
Рассмотрим случай, который, как я предполагаю, довольно распространен. У меня есть следующий класс:
struct Foo
{
Foo(int cost_, int id_) : cost(cost_), id(id_)
{ }
int cost;
int id;
};
Теперь, скажем, я хочу вычислить сумму массива объектов Foo
, используя Foo::cost
.
Я хочу сказать:
std::vector<Foo> vec;
// fill vector with values
int total_cost = std::accumulate(vec.begin(), vec.end(), 0, sum_cost);
И sum_cost
определяется как:
int sum_cost(const Foo& f1, const Foo& f2)
{
return f1.cost + f2.cost;
}
Проблема в том, что это не работает, потому что std::accumulate
ожидает BinaryFunction, которая принимает в двух экземплярах результирующего типа суммы, что в данном случае просто int
. Но как это полезно для меня? Если моя BinaryFunction принимает два int
s, я не могу указать, что я хочу суммировать поле cost
.
Итак, почему std::accumulate
разработан таким образом? Я просто не вижу здесь ничего очевидного?