std::inner_product
| ヘッダ <numeric> で定義
|
||
template< class InputIt1, class InputIt2, class T >
T inner_product( InputIt1 first1, InputIt1 last1,
InputIt2 first2, T init );
|
(1) | (C++20 以降 constexpr) |
template< class InputIt1, class InputIt2, class T,
class BinaryOp1, class BinaryOp2 >
T inner_product( InputIt1 first1, InputIt1 last1,
InputIt2 first2, T init,
BinaryOp1 op1, BinaryOp2 op2 );
|
(2) | (C++20 以降 constexpr) |
範囲 [first1, last1) と std::distance(first1, last1) の first2 から始まる範囲の要素の内積 (積の和) を計算するか、順序付き map/reduce 操作を実行します。
acc (型は T) を初期値 init で初期化し、範囲 acc = acc + (*i1) * (*i2)(C++20 まで)acc = std::move(acc) + (*i1) * (*i2)(C++20 以降) 内のイテレータ i1 と、[first1, last1) の対応するイテレータ i2 (first2 から始まる範囲内) ごとに、式 acc (型は T) を初期値 init で初期化し、範囲 acc = op1(acc, op2(*i1, *i2))(C++20 まで)acc = op1(std::move(acc), op2(*i1, *i2))(C++20 以降) 内のイテレータ i1 と、[first1, last1) の対応するイテレータ i2 (first2 から始まる範囲内) ごとに、式 last2 を std::distance(first1, last1) 番目 の first2 の次のイテレータとしたとき、以下の条件のいずれかが満たされる場合、動作は未定義です:
Tが CopyConstructible ではない。Tが CopyAssignable ではない。op1またはop2が[first1,last1)または[first2,last2)の要素を変更する。op1またはop2が[first1,last1]または[first2,last2]内のイテレータまたはサブ範囲を無効にする。
引数
| first1, last1 | - | 処理する要素の範囲を定義するイテレータのペア |
| first2 | - | 2 番目の要素範囲の先頭 |
| init | - | 積の和の初期値 |
| op1 | - | 適用される二項演算関数オブジェクト。この「和」関数は、op2 の戻り値とアキュムレータの現在値を受け取り、アキュムレータに格納される新しい値を生成します。関数のシグネチャは以下と同等である必要があります:
シグネチャに |
| op2 | - | 適用される二項演算関数オブジェクト。この「積」関数は、各範囲から 1 つの値を受け取り、新しい値を生成します。 関数のシグネチャは以下と同等である必要があります:
シグネチャに |
| 型要件 | ||
-InputIt1, InputIt2 は LegacyInputIterator の要件を満たす必要があります。
| ||
戻り値
acc すべての変更後の値。
実装例
| inner_product (1) |
|---|
template<class InputIt1, class InputIt2, class T>
constexpr // since C++20
T inner_product(InputIt1 first1, InputIt1 last1, InputIt2 first2, T init)
{
while (first1 != last1)
{
init = std::move(init) + (*first1) * (*first2); // std::move since C++20
++first1;
++first2;
}
return init;
}
|
| inner_product (2) |
template<class InputIt1, class InputIt2, class T,
class BinaryOp1, class BinaryOp2>
constexpr // since C++20
T inner_product(InputIt1 first1, InputIt1 last1, InputIt2 first2, T init,
BinaryOp1 op1, BinaryOp2 op2)
{
while (first1 != last1)
{
init = op1(std::move(init), op2(*first1, *first2)); // std::move since C++20
++first1;
++first2;
}
return init;
}
|
ノート
このアルゴリズムの並列化可能なバージョンである std::transform_reduce では、op1 と op2 が可換かつ結合的であることが要求されますが、std::inner_product にはそのような要件はなく、常に指定された順序で操作を実行します。
例
#include <functional>
#include <iostream>
#include <numeric>
#include <vector>
int main()
{
std::vector<int> a{0, 1, 2, 3, 4};
std::vector<int> b{5, 4, 2, 3, 1};
int r1 = std::inner_product(a.begin(), a.end(), b.begin(), 0);
std::cout << "Inner product of a and b: " << r1 << '\n';
int r2 = std::inner_product(a.begin(), a.end(), b.begin(), 0,
std::plus<>(), std::equal_to<>());
std::cout << "Number of pairwise matches between a and b: " << r2 << '\n';
}
出力:
Inner product of a and b: 21
Number of pairwise matches between a and b: 2
欠陥報告
以下の動作変更欠陥報告は、以前に公開された C++ 標準に事後的に適用されました。
| DR | 適用先 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| LWG 242 | C++98 | op1 と op2 に副作用があってはならない
|
関与する範囲を変更できない |
関連項目
(C++17) |
呼び出し可能オブジェクトを適用し、順序を保証せずに結果を集約する (関数テンプレート) |
| 要素範囲を合計または畳み込む (関数テンプレート) | |
| 要素範囲の部分和を計算する (関数テンプレート) |