Cppreference possui este código de exemplo 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; });
Mas também diz:
std::transformnão garante a aplicação em ordem deunary_opoubinary_op. Para aplicar uma função a uma sequência em ordem ou para aplicar uma função que modifica os elementos de uma sequência, usestd::for_each.
Presumivelmente, isso permite implementações paralelas. No entanto, o terceiro parâmetro de std::transformé um LegacyOutputIteratorque possui a seguinte pós-condição para ++r:
Após esta operação,
rnão é necessário incrementar e nenhuma cópia do valor anterior dernão é mais necessária para ser desreferenciável ou incrementável.
Portanto, parece-me que a atribuição da saída deve ocorrer em ordem. Eles simplesmente significam que a aplicação de unary_oppode estar fora de ordem e armazenada em um local temporário, mas copiada na saída em ordem? Isso não soa como algo que você gostaria de fazer.
A maioria das bibliotecas C ++ ainda não implementou executores paralelos, mas a Microsoft implementou. Tenho certeza de que esse é o código relevante e acho que ele chama essa populate()função para gravar iteradores em partes da saída, o que certamente não é uma coisa válida a ser feita, porque LegacyOutputIteratorpode ser invalidada pelo aumento de cópias dele.
o que estou perdendo?
sque invalida os iteradores.
std::transformcom a política de exação, será necessário um iterador de acesso aleatório que back_inserternão pode ser cumprido. A documentação da peça citada pela IMO refere-se a esse cenário. Observe o exemplo nos usos da documentação std::back_inserter.
transformversão que decide se deve ou não usar paralelismo. Otransformpara vetores grandes falha.