STL/диапазоны алгоритм для расчета средневзвешенного

Предположим, у меня есть вектор оценок, где оценка

struct Grade{
   const int grade;
   const int ECTS; // weight
};

Существуют ли алгоритмы/алгоритмы STL/range-v3, которые позволяют мне это делать?

Я знаю, что мог бы сделать это с std:: accumulate с каким-то необычным типом в качестве аккумулятора (который запоминает сумму весов), но я ищу более простую альтернативу, если таковая существует.

Ответы

Ответ 1

Сам тип Grade достаточно причудлив, чтобы действовать как тип аккумулятора.

auto [grade_sum, ects] = std::accumulate(
    grages.begin(), grades.end(), Grade {0,0}, 
    [] (Grade acc, Grade g) -> Grade {
        return { g.grade*g.ECTS + acc.grade,
                 g.ECTS         + acc.ECTS  };
});
// auto average_grade = grade_sum/ects;

Структурное связывание С++ 17 может быть заменено на std::tie при необходимости.

Ответ 2

С range-v3 это может быть:

auto average = ranges::inner_product(grades, grades, 0, {}, {}, &Grade::grade, &Grade::ECTS)
        / double(ranges::accumulate(grades, 0, {}, &Grade::ECTS));

Demo