Namespaces
Variants

std:: inner_product

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
ヘッダー <numeric> で定義
template < class InputIt1, class InputIt2, class T >

T inner_product ( InputIt1 first1, InputIt1 last1,

InputIt2 first2, T init ) ;
(1) (constexpr since C++20)
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) (constexpr since C++20)

内積(すなわち積の和)を計算するか、範囲 [ first1 , last1 ) std:: distance ( first1, last1 ) 個の要素からなる first2 から始まる範囲に対して順序付きmap/reduce操作を実行します。

1) アキュムレータ acc (型 T )を初期値 init で初期化し、その後 acc = acc + ( * i1 ) * ( * i2 ) (C++20まで) acc = std :: move ( acc ) + ( * i1 ) * ( * i2 ) (C++20以降) の式で変更します。範囲 [ first1 , last1 ) 内の各イテレータ i1 と、 first2 から始まる範囲内の対応するイテレータ i2 に対して順次実行されます。+と*の組み込みの意味では、これは2つの範囲の内積を計算します。
2) アキュムレータ acc (型 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 & を持つ必要はありません。
Type1 Type2 は、 T Type3 のオブジェクトがそれぞれ Type1 Type2 に暗黙的に変換可能でなければなりません。型 Ret は、 T 型のオブジェクトに Ret 型の値を代入できるものでなければなりません。 ​

op2 - 適用される二項演算関数オブジェクト。この「積」関数は各範囲から1つの値を受け取り、新しい値を生成します。

関数のシグネチャは以下と同等であるべきです:

Ret fun ( const Type1 & a, const Type2 & b ) ;

シグネチャは const & を持つ必要はありません。
Type1 Type2 は、 InputIt1 InputIt2 のオブジェクトが間接参照され、その後それぞれ Type1 Type2 に暗黙的に変換可能でなければなりません。型 Ret は、 Type3 型のオブジェクトに Ret 型の値を代入できるものでなければなりません。 ​

型要件
-
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;
}
**注記:** - HTMLタグ、属性、および` `, `
`, ``タグ内のテキストは翻訳していません
- C++固有の用語(`inner_product`, `template`, `constexpr`, `InputIt1`, `std::move`など)は翻訳していません
- コメント部分(`// since C++20`, `// std::move since C++20`)は翻訳対象外としました

注記

このアルゴリズムの並列化可能なバージョンである 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 は副作用を持つことができなかった 関連する範囲を変更することはできない

関連項目

呼び出し可能オブジェクトを適用し、非順序でリダクションを行う
(関数テンプレート)
要素の範囲を合計または畳み込む
(関数テンプレート)
要素の範囲の部分和を計算する
(関数テンプレート)