はじめに
C++で、vector
などのコンテナに格納された全要素の合計値を求めたい場合、for
ループを使って一つずつ足し合わせていくのが基本的な方法です。しかし、このような典型的な集計処理のために、標準ライブラリ <numeric>
には、より簡潔で意図の明確な std::accumulate
という便利な関数が用意されています。
accumulate
は、指定された範囲の要素を、初期値から順番に足しこんで(累積して)いき、最終的な結果を返します。また、足し算だけでなく、掛け算や、自作のルールに基づいた集計を行うことも可能です。
この記事では、std::accumulate
の基本的な使い方を、2つのパターンに分けて解説します。
std::accumulate
を使ったサンプルコード
このコードは、vector
に格納された数値の「合計」と「総乗(全ての要素を掛け合わせた値)」を、それぞれ accumulate
を使って計算します。
完成コード
#include <iostream>
#include <vector>
#include <numeric> // accumulate を使うために必要
#include <functional> // multiplies を使うために必要
using namespace std;
int main() {
vector<int> numbers = {10, 2, 5, 3};
// --- 1. 合計値を計算する ---
// 初期値 0 から、numbersの全要素を足し合わせる
int sum_result = accumulate(numbers.begin(), numbers.end(), 0);
cout << "合計値: " << sum_result << endl; // -> 20
// --- 2. 総乗を計算する ---
// 初期値 1 から、numbersの全要素を掛け合わせる
int product_result = accumulate(numbers.begin(), numbers.end(), 1, multiplies<int>());
cout << "総乗: " << product_result << endl; // -> 300
return 0;
}
コードの解説
1. 合計値を計算する場合
accumulate(numbers.begin(), numbers.end(), 0);
これが、accumulate
の最も基本的な使い方です。
- 第1, 2引数: 集計したい要素の範囲をイテレータで指定します。(
numbers.begin()
からnumbers.end()
まで) - 第3引数: 初期値を指定します。合計値を計算する場合、初期値は
0
です。
この呼び出しにより、0 + 10 + 2 + 5 + 3
という計算が内部的に行われ、結果の 20
が返されます。
2. 総乗を計算する場合
accumulate(..., 1, multiplies<int>());
accumulate
は、オプションの第4引数に二項演算(2つの値から一つの値を計算する処理)を指定することで、足し算以外の集計も可能です。
- 第3引数: 総乗を計算する場合、初期値は
1
にします。(0
にすると、結果が常に0になってしまうため) - 第4引数: 演算の種類を指定します。
multiplies<int>()
は、<functional>
ヘッダーで定義されている、掛け算を行う関数オブジェクトです。
この呼び出しにより、1 * 10 * 2 * 5 * 3
という計算が行われ、結果の 300
が返されます。ラムダ式 [](int a, int b){ return a * b; }
を渡すことも可能です。
まとめ
今回は、C++の <numeric>
ライブラリが提供する std::accumulate
を使って、コンテナの要素を効率的に集計する方法を解説しました。
std::accumulate(begin, end, 初期値)
で、範囲内の全要素の合計値を計算できる。- 第4引数に演算を指定することで、合計だけでなく、総乗やその他のカスタム集計も可能。
手動でループを書くよりも、accumulate
を使った方がコードが簡潔になり、「ここでは集計を行っている」という意図が明確になります。