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 начиная с 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 начиная с C++20)

Вычисляет скалярное произведение (т.е. сумму произведений) или выполняет упорядоченную операцию map/reduce для диапазона [ first1 , last1 ) и диапазона из std:: distance ( first1, last1 ) элементов, начинающегося с first2 .

1) Инициализирует аккумулятор acc (типа T ) начальным значением init и затем модифицирует его выражением acc = acc + ( * i1 ) * ( * i2 ) (до C++20) acc = std :: move ( acc ) + ( * i1 ) * ( * i2 ) (начиная с C++20) для каждого итератора i1 в диапазоне [ first1 , last1 ) по порядку и соответствующего ему итератора i2 в диапазоне, начинающемся с first2 . Для встроенных значений + и *, это вычисляет скалярное произведение двух диапазонов.
2) Инициализирует аккумулятор acc (типа 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 & .
Типы Type1 и Type2 должны быть такими, чтобы объекты типов T и Type3 могли быть неявно преобразованы в Type1 и Type2 соответственно. Тип Ret должен быть таким, чтобы объекту типа T можно было присвоить значение типа Ret . ​

op2 - бинарный функциональный объект операции, который будет применён. Эта "производительная" функция принимает по одному значению из каждого диапазона и производит новое значение.

Сигнатура функции должна быть эквивалентна следующей:

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;
}

Примечания

Параллелизуемая версия этого алгоритма, 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 не могли иметь побочных эффектов они не могут изменять задействованные диапазоны

Смотрите также

применяет вызываемый объект, затем выполняет неупорядоченную редукцию
(шаблон функции)
суммирует или сворачивает диапазон элементов
(шаблон функции)
вычисляет частичную сумму диапазона элементов
(шаблон функции)