Can I use std::transform in place with a parallel execution policy?
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).
To quote the standard here
[alg.transform.1]
op [...] shall not invalidate iterators or subranges, or modify elements in the ranges
this forbids your unary_op
to modify either the value given as argument or the container itself.
auto unary_op = [](auto& value)
{
value = 10; // this is bad
return value;
}
auto unary_op = [&vec](auto const& value)
{
vec[0] = value; // also bad
return value;
}
auto unary_op = [&vec](auto& value)
{
vec.erase(vec.begin()); // nope
return value;
}
However, the follwing is ok.
auto unary_op = [](auto& value) // const/ref not strictly needed
{
return value + 10; // totally fine
}
auto unary_op = [&vec](auto& value)
{
return value + vec[0]; // ok in sequential but not in parallel execution
}
Independent from the UnaryOperation
we have
[alg.transform.5]
result may be equal to first in case of unary transform [...].
meaning in-place operations are explicitly allowed.
Now
[algorithms.parallel.overloads.2]
Unless otherwise specified, the semantics of ExecutionPolicy algorithm overloads are identical to their overloads without.
means that the execution policy has no user visible difference on the algorithm. You can expect the algorithm to yield the exact same result as if you wouldn't specify an execution policy.