跳到主要内容

std::inner_product() 算法

// (1)
template< class InputIt1, class InputIt2, class T >
constexpr T inner_product( InputIt1 first1, InputIt1 last1, InputIt2 first2, T init );

// (2)
template< class InputIt1, class InputIt2, class T, class BinaryOperation1, class BinaryOperation2 >
constexpr T inner_product( InputIt1 first1, InputIt1 last1, InputIt2 first2,
T init, BinaryOperation1 op1, BinaryOperation2 op2 );

计算范围 [first1; last1) 和以 first2 开头的范围的内积(即乘积之和)或执行有序的映射/归约操作。

使用初始值 init 初始化累加器 acc(类型为 T),然后用表达式修改它:

  • (1) acc = acc + (*i1) * (*i2) (直到 C++11)acc = std::move(acc) + (*i1) * (*i2) (自 C++11 起)
  • (2) acc = op1(acc, op2(*i1, *i2)) (直到 C++11)acc = op1(std::move(acc), op2(*i1, *i2)) (自 C++11 起)

对于范围 [first1; last1) 中的每个迭代器 i1,以及范围 first2 中对应的迭代器 i2,按顺序执行。

对于 +* 的内置含义,这将计算两个范围的内积。

未定义行为

如果 op1op2 使任何迭代器(包括尾迭代器)失效或修改所涉及范围的任何元素,则行为未定义

.

参数

first1
last1

元素的第一范围。

first2

元素第二范围的起始。

init

乘积的初始值。

op1

将被应用的二元操作函数对象。这个“求和”函数接收 op2 返回的值和累加器的当前值,并生成一个新的值存储在累加器中。

函数的签名应与以下内容等效

Ret fun(const Type1 &a, const Type2 &b);
  • 签名不需要包含 const&
  • 类型 Type1Type2 必须使得类型 TType3 的对象可以分别隐式转换为它们。
  • 类型 Ret 必须使得类型 T 的对象可以被赋予其类型的值。
op2

将被应用的二元操作函数对象。这个“乘积”函数从每个范围中取一个值并生成一个新的值。

函数的签名应与以下内容等效

Ret fun(const Type1 &a, const Type2 &b);
  • 签名不需要包含 const&
  • 类型 Type1Type2 必须使得类型 InputIt1InputIt2 的对象可以被解引用然后分别隐式转换为它们。
  • 类型 Ret 必须使得类型 Type3 的对象可以被赋予其类型的值。

类型要求

InputIt1
InputIt2
LegacyInputIterator
ForwardIt1
ForwardIt2
LegacyForwardIterator
TCopyAssignable
CopyConstructible

返回值

所有修改后的 acc

复杂度

正好是 last - first 次增量、赋值以及 op1op2 的应用。

异常

(无)

可能的实现

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++11
++first1;
++first2;
}

return init;
}
inner_product(2)
template<class InputIt1, class InputIt2, class T,
class BinaryOperation1, class BinaryOperation2>
constexpr // since C++20
T inner_product(InputIt1 first1, InputIt1 last1,
InputIt2 first2, T init,
BinaryOperation1 op1
BinaryOperation2 op2)
{
while (first1 != last1)
{
init = op1(std::move(init), op2(*first1, *first2)); // std::move since C++11
++first1;
++first2;
}

return init;
}

备注

此算法的可并行版本 std::transform_reduce 要求 op1op2 具有交换性和结合性,但 std::inner_product 没有此要求,并且总是按给定顺序执行操作。

示例

Main.cpp
#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
本文源自此 CppReference 页面。它可能因改进或编辑偏好而被修改。点击“编辑此页面”查看本文档的所有更改。
悬停查看原始许可证。

std::inner_product() 算法

// (1)
template< class InputIt1, class InputIt2, class T >
constexpr T inner_product( InputIt1 first1, InputIt1 last1, InputIt2 first2, T init );

// (2)
template< class InputIt1, class InputIt2, class T, class BinaryOperation1, class BinaryOperation2 >
constexpr T inner_product( InputIt1 first1, InputIt1 last1, InputIt2 first2,
T init, BinaryOperation1 op1, BinaryOperation2 op2 );

计算范围 [first1; last1) 和以 first2 开头的范围的内积(即乘积之和)或执行有序的映射/归约操作。

使用初始值 init 初始化累加器 acc(类型为 T),然后用表达式修改它:

  • (1) acc = acc + (*i1) * (*i2) (直到 C++11)acc = std::move(acc) + (*i1) * (*i2) (自 C++11 起)
  • (2) acc = op1(acc, op2(*i1, *i2)) (直到 C++11)acc = op1(std::move(acc), op2(*i1, *i2)) (自 C++11 起)

对于范围 [first1; last1) 中的每个迭代器 i1,以及范围 first2 中对应的迭代器 i2,按顺序执行。

对于 +* 的内置含义,这将计算两个范围的内积。

未定义行为

如果 op1op2 使任何迭代器(包括尾迭代器)失效或修改所涉及范围的任何元素,则行为未定义

.

参数

first1
last1

元素的第一范围。

first2

元素第二范围的起始。

init

乘积的初始值。

op1

将被应用的二元操作函数对象。这个“求和”函数接收 op2 返回的值和累加器的当前值,并生成一个新的值存储在累加器中。

函数的签名应与以下内容等效

Ret fun(const Type1 &a, const Type2 &b);
  • 签名不需要包含 const&
  • 类型 Type1Type2 必须使得类型 TType3 的对象可以分别隐式转换为它们。
  • 类型 Ret 必须使得类型 T 的对象可以被赋予其类型的值。
op2

将被应用的二元操作函数对象。这个“乘积”函数从每个范围中取一个值并生成一个新的值。

函数的签名应与以下内容等效

Ret fun(const Type1 &a, const Type2 &b);
  • 签名不需要包含 const&
  • 类型 Type1Type2 必须使得类型 InputIt1InputIt2 的对象可以被解引用然后分别隐式转换为它们。
  • 类型 Ret 必须使得类型 Type3 的对象可以被赋予其类型的值。

类型要求

InputIt1
InputIt2
LegacyInputIterator
ForwardIt1
ForwardIt2
LegacyForwardIterator
TCopyAssignable
CopyConstructible

返回值

所有修改后的 acc

复杂度

正好是 last - first 次增量、赋值以及 op1op2 的应用。

异常

(无)

可能的实现

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++11
++first1;
++first2;
}

return init;
}
inner_product(2)
template<class InputIt1, class InputIt2, class T,
class BinaryOperation1, class BinaryOperation2>
constexpr // since C++20
T inner_product(InputIt1 first1, InputIt1 last1,
InputIt2 first2, T init,
BinaryOperation1 op1
BinaryOperation2 op2)
{
while (first1 != last1)
{
init = op1(std::move(init), op2(*first1, *first2)); // std::move since C++11
++first1;
++first2;
}

return init;
}

备注

此算法的可并行版本 std::transform_reduce 要求 op1op2 具有交换性和结合性,但 std::inner_product 没有此要求,并且总是按给定顺序执行操作。

示例

Main.cpp
#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
本文源自此 CppReference 页面。它可能因改进或编辑偏好而被修改。点击“编辑此页面”查看本文档的所有更改。
悬停查看原始许可证。