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
Definido en el encabezado <numeric>
template < class InputIt1, class InputIt2, class T >

T inner_product ( InputIt1 first1, InputIt1 last1,

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

Calcula el producto interno (es decir, la suma de productos) o realiza una operación ordenada de map/reduce en el rango [ first1 , last1 ) y el rango de std:: distance ( first1, last1 ) elementos comenzando en first2 .

1) Inicializa el acumulador acc (de tipo T ) con el valor inicial init y luego lo modifica con la expresión acc = acc + ( * i1 ) * ( * i2 ) (hasta C++20) acc = std :: move ( acc ) + ( * i1 ) * ( * i2 ) (desde C++20) para cada iterador i1 en el rango [ first1 , last1 ) en orden y su iterador correspondiente i2 en el rango que comienza en first2 . Para el significado incorporado de + y *, esto calcula el producto interno de los dos rangos.
2) Inicializa el acumulador acc (de tipo T ) con el valor inicial init y luego lo modifica con la expresión acc = op1 ( acc, op2 ( * i1, * i2 ) ) (hasta C++20) acc = op1 ( std :: move ( acc ) , op2 ( * i1, * i2 ) ) (desde C++20) para cada iterador i1 en el rango [ first1 , last1 ) en orden y su iterador correspondiente i2 en el rango que comienza en first2 .

Dado last2 como el std:: distance ( first1, last1 ) ésimo siguiente iterador de first2 , si se satisface alguna de las siguientes condiciones, el comportamiento es indefinido:

  • T no es CopyConstructible .
  • T no es CopyAssignable .
  • op1 o op2 modifica cualquier elemento de [ first1 , last1 ) o [ first2 , last2 ) .
  • op1 o op2 invalida cualquier iterador o subrango en [ first1 , last1 ] o [ first2 , last2 ] .

Contenidos

Parámetros

first1, last1 - el par de iteradores que define el rango de elementos a
first2 - el inicio del segundo rango de elementos
init - valor inicial de la suma de los productos
op1 - objeto función de operación binaria que será aplicado. Esta función "suma" toma un valor devuelto por op2 y el valor actual del acumulador y produce un nuevo valor para almacenar en el acumulador.

La firma de la función debe ser equivalente a la siguiente:

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

La firma no necesita tener const & .
Los tipos Type1 y Type2 deben ser tales que objetos de tipos T y Type3 puedan convertirse implícitamente a Type1 y Type2 respectivamente. El tipo Ret debe ser tal que un objeto de tipo T pueda asignarse un valor de tipo Ret . ​

op2 - objeto función de operación binaria que será aplicado. Esta función "producto" toma un valor de cada rango y produce un nuevo valor.

La firma de la función debe ser equivalente a la siguiente:

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

La firma no necesita tener const & .
Los tipos Type1 y Type2 deben ser tales que objetos de tipos InputIt1 y InputIt2 puedan ser desreferenciados y luego convertidos implícitamente a Type1 y Type2 respectivamente. El tipo Ret debe ser tal que un objeto de tipo Type3 pueda asignarse un valor de tipo Ret . ​

Requisitos de tipo
-
InputIt1, InputIt2 deben cumplir con los requisitos de LegacyInputIterator .

Valor de retorno

acc después de todas las modificaciones.

Implementación posible

inner_product (1)
template<class InputIt1, class InputIt2, class T>
constexpr // desde C++20
T inner_product(InputIt1 first1, InputIt1 last1, InputIt2 first2, T init)
{
    while (first1 != last1)
    {
        init = std::move(init) + (*first1) * (*first2); // std::move desde C++20
        ++first1;
        ++first2;
    }
    return init;
}
inner_product (2)
template<class InputIt1, class InputIt2, class T,
         class BinaryOp1, class BinaryOp2>
constexpr // desde 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 desde C++20
        ++first1;
        ++first2;
    }
    return init;
}

Notas

La versión paralelizable de este algoritmo, std::transform_reduce , requiere que op1 y op2 sean conmutativos y asociativos, pero std::inner_product no impone tal requisito, y siempre ejecuta las operaciones en el orden especificado.

Ejemplo

#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 << "Producto interno de a y b: " << r1 << '\n';
    int r2 = std::inner_product(a.begin(), a.end(), b.begin(), 0,
                                std::plus<>(), std::equal_to<>());
    std::cout << "Número de coincidencias por pares entre a y b: " <<  r2 << '\n';
}

Salida:

Inner product of a and b: 21
Number of pairwise matches between a and b: 2

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.

DR Aplicado a Comportamiento publicado Comportamiento correcto
LWG 242 C++98 op1 y op2 no podían tener efectos secundarios no pueden modificar los rangos involucrados

Véase también

aplica un invocable, luego reduce sin orden
(plantilla de función)
suma o pliega un rango de elementos
(plantilla de función)
calcula la suma parcial de un rango de elementos
(plantilla de función)