std:: accumulate
|
ヘッダーで定義
<numeric>
|
||
|
template
<
class
InputIt,
class
T
>
T accumulate ( InputIt first, InputIt last, T init ) ; |
(1) | (constexpr since C++20) |
|
template
<
class
InputIt,
class
T,
class
BinaryOp
>
T accumulate ( InputIt first, InputIt last, T init, BinaryOp op ) ; |
(2) | (constexpr since C++20) |
指定された値
init
と範囲
[
first
,
last
)
内の要素の合計を計算します。
T
)を初期値
init
で初期化し、その後範囲
[
first
,
last
)
内の各イテレータ
i
に対して順番に
acc
=
acc
+
*
i
(C++20まで)
acc
=
std
::
move
(
acc
)
+
*
i
(C++20以降)
で変更します。
T
)を初期値
init
で初期化し、その後範囲
[
first
,
last
)
内の各イテレータ
i
に対して順番に
acc
=
op
(
acc,
*
i
)
(C++20まで)
acc
=
op
(
std
::
move
(
acc
)
,
*
i
)
(C++20以降)
で更新します。
以下のいずれかの条件が満たされる場合、動作は未定義です:
-
Tは CopyConstructible ではありません。 -
Tは CopyAssignable ではありません。 -
op
が
[first,last)の任意の要素を変更します。 -
op
が
[first,last]内の任意のイテレータまたは部分範囲を無効化します。
目次 |
パラメータ
| first, last | - | 累積する要素の範囲を定義するイテレータのペア |
| init | - | 累積の初期値 |
| op | - |
適用される二項演算関数オブジェクト。
関数のシグネチャは以下と同等であるべきです: Ret fun ( const Type1 & a, const Type2 & b ) ;
シグネチャは
const
&
を持つ必要はありません。
|
| 型要件 | ||
-
InputIt
は
LegacyInputIterator
の要件を満たさなければなりません。
|
||
戻り値
acc すべての変更後。
実装例
| accumulate (1) |
|---|
template<class InputIt, class T> constexpr // since C++20 T accumulate(InputIt first, InputIt last, T init) { for (; first != last; ++first) init = std::move(init) + *first; // std::move since C++20 return init; } |
| accumulate (2) |
template<class InputIt, class T, class BinaryOperation> constexpr // since C++20 T accumulate(InputIt first, InputIt last, T init, BinaryOperation op) { for (; first != last; ++first) init = op(std::move(init), *first); // std::move since C++20 return init; } |
注記
std::accumulate
は左
fold
を実行します。右foldを実行するには、二項演算子への引数の順序を逆にし、逆方向イテレータを使用する必要があります。
型推論に任せた場合、 op は init と同じ型の値に対して演算を行うため、イテレータ要素の望ましくない型変換が発生する可能性があります。例えば、 std :: accumulate ( v. begin ( ) , v. end ( ) , 0 ) は、 v の型が std:: vector < double > の場合、期待される結果を返さない可能性があります。
例
#include <functional> #include <iostream> #include <numeric> #include <string> #include <vector> int main() { std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int sum = std::accumulate(v.begin(), v.end(), 0); int product = std::accumulate(v.begin(), v.end(), 1, std::multiplies<int>()); auto dash_fold = [](std::string a, int b) { return std::move(a) + '-' + std::to_string(b); }; std::string s = std::accumulate(std::next(v.begin()), v.end(), std::to_string(v[0]), // 最初の要素から開始 dash_fold); // 逆イテレータを使用した右畳み込み std::string rs = std::accumulate(std::next(v.rbegin()), v.rend(), std::to_string(v.back()), // 最後の要素から開始 dash_fold); std::cout << "sum: " << sum << '\n' << "product: " << product << '\n' << "dash-separated string: " << s << '\n' << "dash-separated string (right-folded): " << rs << '\n'; }
出力:
sum: 55 product: 3628800 dash-separated string: 1-2-3-4-5-6-7-8-9-10 dash-separated string (right-folded): 10-9-8-7-6-5-4-3-2-1
不具合報告
以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | 適用対象 | 公開時の動作 | 正しい動作 |
|---|---|---|---|
| LWG 242 | C++98 | op 副作用を持つことができなかった | 関連する範囲を変更することはできない |
関連項目
|
範囲内の隣接する要素間の差を計算する
(関数テンプレート) |
|
|
2つの範囲の要素の内積を計算する
(関数テンプレート) |
|
|
範囲の要素の部分和を計算する
(関数テンプレート) |
|
|
(C++17)
|
std::accumulate
と類似しているが、順序不同で実行される
(関数テンプレート) |
|
(C++23)
|
範囲の要素を左から畳み込む
(アルゴリズム関数オブジェクト) |