If I am not mistaken, I can make std::transform
perform in place by using the same range as an input and output iterator. Assume I have some std::vector
object vec
, then I would write
std::transform(vec.cbegin(),vec.cend(),vec.begin(),unary_op)
using a suitable unary operation unary_op
.
Using the C++17 standard, I would like to execute the transform in parallel by sticking an std::execution::par
in there as the first argument. This would make the function go from overload (1) to (2) in the cppreference article on std::transform
. However the comments to this overload says:
unary_op
[...] must not invalidate any iterators, including the end iterators, or modify any elements of the ranges involved. (since C++11)
Does "modify any elements" really mean I cannot use the algorithm in place or is this talking about a different detail that I misinterpreted?
I believe that it's talking about a different detail. The unary_op
takes an element of the sequence and returns a value. That value is stored (by transform
) into the destination sequence.
So this unary_op
would be fine:
int times2(int v) { return 2*v; }
but this one would not:
int times2(int &v) { return v*=2; }
But that's not really what you're asking about.
You want to know if you can use the unary_op
version of transform
as a parallel algorithm with the same source and destination range. I don't see why not. transform
maps a single element of the source sequence to a single element of the destination sequence. However, if your unary_op
isn't really unary, (i.e, it references other elements in the sequence - even if it only reads them, then you will have a data race).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With