Cppreference a cet exemple de code pour 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; });
Mais cela dit aussi:
std::transform
ne garantit pas l'application dans l'ordre deunary_op
oubinary_op
. Pour appliquer une fonction à une séquence dans l'ordre ou pour appliquer une fonction qui modifie les éléments d'une séquence, utilisezstd::for_each
.
C'est probablement pour permettre des implémentations parallèles. Cependant, le troisième paramètre de std::transform
est un LegacyOutputIterator
qui a la postcondition suivante pour ++r
:
Après cette opération, il
r
n'est pas nécessaire d'être incrémentable et aucune copie de la valeur précédente der
ne doit plus être déréférencable ou incrémentable.
Il me semble donc que l'affectation de la sortie doit se faire dans l'ordre. Signifient-ils simplement que l'application de unary_op
peut être hors service et stockée dans un emplacement temporaire, mais copiée dans l'ordre de sortie? Cela ne ressemble pas à quelque chose que vous voudriez faire.
La plupart des bibliothèques C ++ n'ont pas encore implémenté d'exécuteurs parallèles, mais Microsoft l'a fait. Je suis sûr que c'est le code correspondant, et je pense qu'il appelle cette fonction pour enregistrer des morceaux de itérateurs à la sortie, ce qui est certainement pas une chose valable de le faire parce que peut être invalidée par incrémenter copies.populate()
LegacyOutputIterator
Qu'est-ce que je rate?
s
, ce qui invalide les itérateurs.
std::transform
avec la politique d'exaction, un itérateur d'accès aléatoire est requis, ce qui back_inserter
ne peut pas être réalisé. La documentation des pièces citées par l'OMI fait référence à ce scénario. Notez l'exemple dans la documentation utilise std::back_inserter
.
transform
version qui décide d'utiliser ou non le paralélisme. Letransform
pour les grands vecteurs échoue.