std:: inner_product
|
ヘッダー
<numeric>
で定義
|
||
|
template
<
class
InputIt1,
class
InputIt2,
class
T
>
T inner_product
(
InputIt1 first1, InputIt1 last1,
|
(1) | (constexpr since C++20) |
|
template
<
class
InputIt1,
class
InputIt2,
class
T,
class
BinaryOp1,
class
BinaryOp2
>
|
(2) | (constexpr since C++20) |
内積(すなわち積の和)を計算するか、範囲
[
first1
,
last1
)
と
std::
distance
(
first1, last1
)
個の要素からなる
first2
から始まる範囲に対して順序付きmap/reduce操作を実行します。
T
)を初期値
init
で初期化し、その後
acc
=
acc
+
(
*
i1
)
*
(
*
i2
)
(C++20まで)
acc
=
std
::
move
(
acc
)
+
(
*
i1
)
*
(
*
i2
)
(C++20以降)
の式で変更します。範囲
[
first1
,
last1
)
内の各イテレータ
i1
と、
first2
から始まる範囲内の対応するイテレータ
i2
に対して順次実行されます。+と*の組み込みの意味では、これは2つの範囲の内積を計算します。
T
)を初期値
init
で初期化し、その後、範囲
[
first1
,
last1
)
内の各イテレータ
i1
と、
first2
から始まる範囲内の対応するイテレータ
i2
に対して、順序通りに以下の式で変更します:
acc
=
op1
(
acc, op2
(
*
i1,
*
i2
)
)
(C++20まで)
acc
=
op1
(
std
::
move
(
acc
)
, op2
(
*
i1,
*
i2
)
)
(C++20以降)
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
によって返された値とアキュムレータの現在の値を受け取り、アキュムレータに格納される新しい値を生成します。
関数のシグネチャは以下と同等であるべきです: Ret fun ( const Type1 & a, const Type2 & b ) ;
シグネチャは
const
&
を持つ必要はありません。
|
| op2 | - |
適用される二項演算関数オブジェクト。この「積」関数は各範囲から1つの値を受け取り、新しい値を生成します。
関数のシグネチャは以下と同等であるべきです: Ret fun ( const Type1 & a, const Type2 & b ) ;
シグネチャは
const
&
を持つ必要はありません。
|
| 型要件 | ||
-
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 << "aとbの内積: " << r1 << '\n'; int r2 = std::inner_product(a.begin(), a.end(), b.begin(), 0, std::plus<>(), std::equal_to<>()); std::cout << "aと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)
|
呼び出し可能オブジェクトを適用し、非順序でリダクションを行う
(関数テンプレート) |
|
要素の範囲を合計または畳み込む
(関数テンプレート) |
|
|
要素の範囲の部分和を計算する
(関数テンプレート) |