Cppreference имеет этот пример кода для 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; });
Но это также говорит:
std::transformне гарантирует применение в порядкеunary_opилиbinary_op. Чтобы применить функцию к последовательности по порядку или применить функцию, которая изменяет элементы последовательности, используйтеstd::for_each.
Предположительно, это допускает параллельные реализации. Однако третий параметр std::transformпредставляет собой LegacyOutputIteratorследующее условие ++r:
После этой операции
rнет необходимости увеличивать ее, и любые копии предыдущего значенияrбольше не должны быть разыменованными или увеличиваемыми.
Поэтому мне кажется, что назначение вывода должно происходить по порядку. Означают ли они просто, что приложение unary_opможет быть не в порядке и сохранено во временном местоположении, но скопировано в выходные данные по порядку? Это не похоже на то, что вы когда-либо хотели бы сделать.
Большинство библиотек C ++ на самом деле еще не реализовали параллельных исполнителей, но Microsoft имеет. Я почти уверен, что это релевантный код, и я думаю, что он вызывает эту populate()функцию для записи итераторов в порции вывода, что, безусловно, не является допустимым действием, поскольку его LegacyOutputIteratorможно сделать недействительным, увеличив его копии.
Что мне не хватает?
s, что делает итераторы недействительными.
std::transformполитику exaction, то необходим итератор произвольного доступа, который back_inserterне может быть выполнен. ИМО цитирует часть документации, относящейся к этому сценарию. Обратите внимание на пример использования документации std::back_inserter.
transformверсией, которая решает, использовать ли паралелизм или нет. Дляtransformбольших векторов не удается.