Cppreference tiene este código de ejemplo para std::transform
:
std::vector<std::size_t> ordinals;
std::transform(s.begin(), s.end(), std::back_inserter(ordinals),
[](unsigned char c) -> std::size_t { return c; });
Pero también dice:
std::transform
no garantiza la aplicación en orden deunary_op
obinary_op
. Para aplicar una función a una secuencia en orden o para aplicar una función que modifique los elementos de una secuencia, usestd::for_each
.
Esto es presumiblemente para permitir implementaciones paralelas. Sin embargo, el tercer parámetro de std::transform
es un LegacyOutputIterator
que tiene la siguiente condición posterior para ++r
:
Después de esta operación
r
no se requiere que sea incrementable y ya no se requiere que las copias del valor anteriorr
sean desreferenciables o incrementables
Entonces me parece que la asignación de la salida debe ocurrir en orden. ¿Simplemente significan que la aplicación de unary_op
puede estar fuera de servicio y almacenada en una ubicación temporal, pero copiada a la salida en orden? Eso no suena como algo que alguna vez quieras hacer.
La mayoría de las bibliotecas de C ++ aún no han implementado ejecutores paralelos, pero Microsoft sí. Estoy bastante seguro de que este es el código relevante, y creo que llama a esta populate()
función para grabar iteradores en fragmentos de la salida, lo que seguramente no es algo válido porque LegacyOutputIterator
puede invalidarse incrementando copias de él.
¿Qué me estoy perdiendo?
s
, lo que invalida los iteradores.
std::transform
política de exacción, se requiere un iterador de acceso aleatorio que back_inserter
no puede cumplir. La documentación de la parte citada por la OMI se refiere a ese escenario. Ejemplo de nota en usos de documentación std::back_inserter
.
transform
versión que decide si se usa o no el paralelismo. Eltransform
para vectores grandes falla.