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
больших векторов не удается.