std::inner_product
| 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 interior (es decir, suma de productos) o realiza una operación ordenada de mapa/reducción en el rango [first1, last1) y el rango de std::distance(first1, last1) elementos que comienza en first2.
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. Con el significado intrínseco de + y *, esto calcula el producto interior de los dos rangos.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 cumple alguna de las siguientes condiciones, el comportamiento no está definido:
Tno es CopyConstructible.Tno es CopyAssignable.op1oop2modifica cualquier elemento de[first1,last1)o[first2,last2).op1oop2invalida cualquier iterador o subrango en[first1,last1]o[first2,last2].
Parámetros
| first1, last1 | - | el par de iteradores que definen 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 se aplicará. 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:
La firma no necesita tener |
| op2 | - | objeto función de operación binaria que se aplicará. 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:
La firma no necesita tener |
| Requisitos de tipo | ||
-InputIt1, InputIt2 debe cumplir los requisitos de LegacyInputIterator.
| ||
Valor de retorno
acc después de todas las modificaciones.
Posible implementación
| 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;
}
|
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 realiza las operaciones en el orden dado.
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 << "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';
}
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 cambian el comportamiento se aplicaron retroactivamente a los estándares C++ previamente publicados.
| DR | Aplicado a | Comportamiento según lo 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
(C++17) |
aplica un invocable, luego reduce fuera de 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) |