Cppreference ma ten przykładowy kod dla 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; });
Ale mówi również:
std::transformnie gwarantuje zastosowaniaunary_oplubbinary_op. Aby zastosować funkcję do sekwencji w kolejności lub zastosować funkcję, która modyfikuje elementy sekwencji, użyjstd::for_each.
Ma to prawdopodobnie umożliwić równoległe wdrożenia. Jednak trzecim parametrem std::transformjest LegacyOutputIteratornastępujący warunek ++r:
Po tej operacji
rnie wymaga się, aby była inkrementowalna, a wszelkie kopie poprzedniej wartościrnie muszą już być dereferencyjne ani inkrementowalne.
Wydaje mi się więc, że przyporządkowanie danych wyjściowych musi nastąpić po kolei. Czy oznaczają one po prostu, że aplikacja unary_opmoże być nieczynna i przechowywana w tymczasowej lokalizacji, ale kopiowana na wyjście w odpowiedniej kolejności? To nie brzmi jak coś, co kiedykolwiek chciałbyś zrobić.
Większość bibliotek C ++ nie zaimplementowało jeszcze równoległych programów wykonawczych, ale Microsoft ma. Jestem prawie pewien, że jest to odpowiedni kod i myślę, że wywołuje tę populate()funkcję, aby rejestrować iteratory w porcjach danych wyjściowych, co z pewnością nie jest prawidłową rzeczą, ponieważ LegacyOutputIteratormoże zostać unieważnione przez zwiększenie jej kopii.
czego mi brakuje?
s, co unieważnia iteratory.
std::transformz zasad exaction, wymagany jest iterator o dostępie swobodnym, który back_inserternie może spełnić. Cytowana przez IMO dokumentacja części odnosi się do tego scenariusza. Uwaga przykład w zastosowaniach dokumentacji std::back_inserter.
transformwersją, która decyduje, czy użyć paralelizmu. Wtransformprzypadku dużych wektorów zawodzi.