C++ std::accumulateについてざっくり調べてみた

これまでstd::accumulate()を使用する場面に遭遇すると、
その都度なんとなく調べて使ってました。
そして今日もstd::accumulate()を使う場面があり、コロナで暇なので、少しアウトプットしてみた。
アウトプットすることで思考の整理ができ、記憶に定着するのだ!!と、誰かが言ってました。


自分的に信頼できるcpprefjp - C++日本語リファレンスに記載があったひとことが端的に表してらっしゃる。

- accumulate()は、範囲を集計する関数である。

なるほど。


フル定義は下記↓↓

#include <numeric>

template <class InputIterator, class T, class BinaryOperation>
std::accumulate(
    InputIterator first,
    InputIterator last,
    T init,    // 省略可能。デフォルト:1
    BinaryOperation binary_op); // 省略可能。デフォルト:Add
  • "init" で初期値を変更することができる。
  • "binary_op"で、算術を指定することができる。

自分がわかりにくかった点は、binary_opの引数が、毎回何が代入されているのかとしっくりこなかった✕

例えば、(※これも冒頭のcpprefjp - C++日本語リファレンスに記載の例)

std::vector<int> v = {1, 2, 3, 4, 5};
product = std::accumulate(v.begin(), v.end(), 1, [](int acc, int i) {
    return acc * i;
  });

lambda関数の引数"acc""i"ってどこからくるんじゃい!!
何が代入されるんじゃい!!と。

結論は、↓↓であります。

- init(accumulateの第3引数) = binary_op(init, *iter)

初期値をどんどん再帰的にアップデートしていく感じになります。
なるほど。 上記の例で具体的にいうと、

初期値"init=1"が
- (((init*iter)*iter)*iter)*iter)
とこんな感じで雪だるま式に増えていきます。
んー、なんか借金の利子みたいな。。


やっぱり、アウトプットすると自分が理解できていなかったことが浮き彫りになりますな。