std:: partial_sum
|
ヘッダー
<numeric>
で定義
|
||
|
template
<
class
InputIt,
class
OutputIt
>
OutputIt partial_sum
(
InputIt first, InputIt last,
|
(1) | (constexpr since C++20) |
|
template
<
class
InputIt,
class
OutputIt,
class
BinaryOp
>
OutputIt partial_sum
(
InputIt first, InputIt last,
|
(2) | (constexpr since C++20) |
[
first
,
last
)
が空の場合、何も行わない。
-
アキュムレータ
acc
を作成します。その型は
value type
であり、
InputItの値型で初期化され、 * first で初期化されます。 - acc を * d_first に代入します。
-
各整数
i
に対して、
[1,std:: distance ( first, last ))の範囲で、以下の操作を順番に実行します:
実際の二項演算として binary_op が与えられた場合:
- 以下のいずれかの条件が満たされる場合、プログラムは不適格となります:
-
-
InputItの値型が * first から構築可能でない。 - acc が 書き込み可能 で d_first に書き込めない。
-
binary_op
(
acc,
*
iter
)
(C++20以前)
binary_op
(
std
::
move
(
acc
)
,
*
iter
)
(C++20以降)
の結果が
InputItの値型に暗黙変換できない。
-
- d_last が返されるイテレータとして与えられた場合、以下のいずれかの条件が満たされると、動作は未定義となります:
-
-
binary_op
は
[first,last)または[d_first,d_last)の任意の要素を変更する可能性があります。 -
binary_op
は
[first,last]または[d_first,d_last]内の任意のイテレータまたは部分範囲を無効化する可能性があります。
-
binary_op
は
- ↑ 実際に代入される値は、前のステップでの代入結果です。ここでは代入結果が acc であると仮定します。
目次 |
パラメータ
| first, last | - | 合計する要素の範囲を定義するイテレータのペア |
| d_first | - | 宛先範囲の先頭。 first と等しくてもよい |
| op | - |
適用される二項演算関数オブジェクト。
関数のシグネチャは以下と同等であるべきです: Ret fun ( const Type1 & a, const Type2 & b ) ;
シグネチャは
const
&
を持つ必要はありません。
|
| 型要件 | ||
-
InputIt
は
LegacyInputIterator
の要件を満たさなければなりません。
|
||
-
OutputIt
は
LegacyOutputIterator
の要件を満たさなければなりません。
|
||
戻り値
書き込まれた最後の要素の次の要素を指すイテレータ、または
d_first
が返される(
[
first
,
last
)
が空の場合)。
計算量
与えられた N を std:: distance ( first, last ) として:
実装例
| partial_sum (1) |
|---|
template<class InputIt, class OutputIt> constexpr // since C++20 OutputIt partial_sum(InputIt first, InputIt last, OutputIt d_first) { if (first == last) return d_first; typename std::iterator_traits<InputIt>::value_type sum = *first; *d_first = sum; while (++first != last) { sum = std::move(sum) + *first; // std::move since C++20 *++d_first = sum; } return ++d_first; // or, since C++14: // return std::partial_sum(first, last, d_first, std::plus<>()); } |
| partial_sum (2) |
template<class InputIt, class OutputIt, class BinaryOp> constexpr // since C++20 OutputIt partial_sum(InputIt first, InputIt last, OutputIt d_first, BinaryOp op) { if (first == last) return d_first; typename std::iterator_traits<InputIt>::value_type acc = *first; *d_first = acc; while (++first != last) { acc = op(std::move(acc), *first); // std::move since C++20 *++d_first = acc; } return ++d_first; } |
注記
acc は、 LWG issue 539 の解決により導入されました。 acc を使用する理由(すなわち、直接結果を合計する * ( d_first + 2 ) = ( * first + * ( first + 1 ) ) + * ( first + 2 ) ; の代わりに)は、以下の型が一致しない場合に後者の意味が曖昧になるためです:
-
InputItの値型 -
OutputItの書き込み可能な型 - operator + または op のパラメータの型
- operator + または op の戻り値の型
acc は、計算の各ステップで値を保存および提供する中間オブジェクトとして機能します:
-
その型は
InputItの値型である - それは d_first に書き込まれる
- その値は operator + または op に渡される
- それは operator + または op の戻り値を格納する
enum not_int { x = 1, y = 2 }; char i_array[4] = {100, 100, 100, 100}; not_int e_array[4] = {x, x, y, y}; int o_array[4]; // OK: operator+(char, char)を使用し、char値をint配列に代入 std::partial_sum(i_array, i_array + 4, o_array); // エラー: not_int値をint配列に代入できません std::partial_sum(e_array, e_array + 4, o_array); // OK: 必要時に変換を実行 // 1. 型char(値型)の「acc」を作成 // 2. char引数はlong乗算に使用(char -> long) // 3. longの積が「acc」に代入(long -> char) // 4. 「acc」が「o_array」の要素に代入(char -> int) // 5. 入力範囲の残りの要素を処理するためステップ2に戻る std::partial_sum(i_array, i_array + 4, o_array, std::multiplies<long>{});
例
#include <functional> #include <iostream> #include <iterator> #include <numeric> #include <vector> int main() { std::vector<int> v(10, 2); // v = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2} std::cout << "最初の " << v.size() << " 個の偶数: "; // 結果をcoutストリームに出力 std::partial_sum(v.cbegin(), v.cend(), std::ostream_iterator<int>(std::cout, " ")); std::cout << '\n'; // 結果をベクトルvに書き戻す std::partial_sum(v.cbegin(), v.cend(), v.begin(), std::multiplies<int>()); std::cout << "最初の " << v.size() << " 個の2の累乗: "; for (int n : v) std::cout << n << ' '; std::cout << '\n'; }
出力:
最初の 10 個の偶数: 2 4 6 8 10 12 14 16 18 20 最初の 10 個の2の累乗: 2 4 8 16 32 64 128 256 512 1024
不具合報告
以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | 適用対象 | 公開時の動作 | 正しい動作 |
|---|---|---|---|
| LWG 242 | C++98 | op 副作用を持つことができなかった | 関連する範囲を変更できない |
| LWG 539 | C++98 |
結果の評価と代入が有効となるための
型要件が欠落していた |
追加された |
関連項目
|
範囲内の隣接する要素間の差分を計算する
(関数テンプレート) |
|
|
範囲の要素を合計または畳み込む
(関数テンプレート) |
|
|
(C++17)
|
std::partial_sum
と類似しており、
i
番目
の入力要素を
i
番目
の合計に含める
(関数テンプレート) |
|
(C++17)
|
std::partial_sum
と類似しており、
i
番目
の入力要素を
i
番目
の合計から除外する
(関数テンプレート) |