名稱空間
變體
操作

std::inner_product

來自 cppreference.com
< cpp‎ | 演算法
 
 
演算法庫
有約束演算法與針對範圍的演算法 (C++20)
有約束的演算法,例如 ranges::copyranges::sort 等……
執行策略 (C++17)
排序及相關操作
劃分操作
排序操作
二分搜尋操作
(於已劃分範圍上)
集合操作(於已排序範圍上)
歸併操作(於已排序範圍上)
堆操作
最小/最大值操作
(C++11)
(C++17)
字典序比較操作
排列操作
C 庫
數值操作
(C++11)
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)

計算內積(即乘積之和)或對範圍 [first1last1) 以及以 first2 開頭的 std::distance(first1, last1) 個元素的範圍執行有序的對映/歸約操作。

1) 使用初始值 init 初始化累加器 acc (型別為 T),然後按順序對範圍 [first1last1) 中的每個迭代器 i1 及其在以 first2 開頭的範圍中對應的迭代器 i2,使用表示式 acc = acc + (*i1) * (*i2)(C++20 前)acc = std::move(acc) + (*i1) * (*i2)(C++20 起) 來修改它。對於 + 和 * 的內建含義,這將計算兩個範圍的內積。
2) 使用初始值 init 初始化累加器 acc (型別為 T),然後按順序對範圍 [first1last1) 中的每個迭代器 i1 及其在以 first2 開頭的範圍中對應的迭代器 i2,使用表示式 acc = op1(acc, op2(*i1, *i2))(C++20 前)acc = op1(std::move(acc), op2(*i1, *i2))(C++20 起) 來修改它。

給定 last2 作為 first2std::distance(first1, last1) 個下一個迭代器,如果滿足以下任何條件,則行為未定義:

目錄

[編輯] 引數

first1, last1 - 定義要處理元素的範圍的迭代器對
first2 - 第二個元素範圍的起始
init - 乘積之和的初始值
op1 - 將應用的二元操作函式物件。此“求和”函式接受一個由 op2 返回的值和累加器的當前值,並生成一個新值儲存在累加器中。

函式的簽名應等效於以下內容

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

簽名不需要有 const &
型別  Type1 Type2 必須使得型別 TType3 的物件可以分別隱式轉換為  Type1 Type2。型別 Ret 必須使得型別 T 的物件可以被賦值為型別 Ret 的值。​

op2 - 將應用的二元操作函式物件。此“乘積”函式從每個範圍取一個值並生成一個新值。

函式的簽名應等效於以下內容

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

簽名不需要有 const &
型別  Type1 Type2 必須使得型別 InputIt1InputIt2 的物件可以被解引用,然後分別隱式轉換為  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;
}

[編輯] 注意

此演算法的可並行版本 std::transform_reduce 要求 op1op2 具有交換性和結合性,但 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++ 標準。

缺陷報告 應用於 釋出時的行為 正確的行為
LWG 242 C++98 op1op2 不得有副作用 它們不能修改所涉及的範圍

[編輯] 另請參閱

應用一個可呼叫物件,然後進行亂序歸約
(函式模板) [編輯]
對一個範圍的元素進行求和或摺疊
(函式模板) [編輯]
計算一個範圍元素的部分和
(函式模板) [編輯]