std:: inner_product
|
Определено в заголовке
<numeric>
|
||
|
template
<
class
InputIt1,
class
InputIt2,
class
T
>
T inner_product
(
InputIt1 first1, InputIt1 last1,
|
(1) | (constexpr начиная с C++20) |
|
template
<
class
InputIt1,
class
InputIt2,
class
T,
class
BinaryOp1,
class
BinaryOp2
>
|
(2) | (constexpr начиная с C++20) |
Вычисляет скалярное произведение (т.е. сумму произведений) или выполняет упорядоченную операцию map/reduce для диапазона
[
first1
,
last1
)
и диапазона из
std::
distance
(
first1, last1
)
элементов, начинающегося с
first2
.
T
) начальным значением
init
и затем модифицирует его выражением
acc
=
acc
+
(
*
i1
)
*
(
*
i2
)
(до C++20)
acc
=
std
::
move
(
acc
)
+
(
*
i1
)
*
(
*
i2
)
(начиная с C++20)
для каждого итератора
i1
в диапазоне
[
first1
,
last1
)
по порядку и соответствующего ему итератора
i2
в диапазоне, начинающемся с
first2
. Для встроенных значений + и *, это вычисляет скалярное произведение двух диапазонов.
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 | - | начало второго диапазона элементов |
| init | - | начальное значение суммы произведений |
| op1 | - |
бинарный функциональный объект операции, который будет применён. Эта "суммирующая" функция принимает значение, возвращаемое
op2
и текущее значение аккумулятора, и производит новое значение для сохранения в аккумуляторе.
Сигнатура функции должна быть эквивалентна следующей: Ret fun ( const Type1 & a, const Type2 & b ) ;
Сигнатура не обязана иметь
const
&
.
|
| op2 | - |
бинарный функциональный объект операции, который будет применён. Эта "производительная" функция принимает по одному значению из каждого диапазона и производит новое значение.
Сигнатура функции должна быть эквивалентна следующей: 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 << "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 | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| LWG 242 | C++98 | op1 и op2 не могли иметь побочных эффектов | они не могут изменять задействованные диапазоны |
Смотрите также
|
(C++17)
|
применяет вызываемый объект, затем выполняет неупорядоченную редукцию
(шаблон функции) |
|
суммирует или сворачивает диапазон элементов
(шаблон функции) |
|
|
вычисляет частичную сумму диапазона элементов
(шаблон функции) |