Reputation: 22347
Is the compiler allowed to eliminate the copy that is required for the by-value capture?
vector<Image> movie1;
apply( [=movie1](){ return movie1.size(); } );
movie1
?
apply
does not actually change movie1
?const
functors in any case?vector
has a move constructor and move assign?
Image
as well, to prevent an expensive copy here?void operate(vector<Image> movie)
?Upvotes: 14
Views: 1167
Reputation: 248289
There is always the "as-if" rule. As long as it looks as if the rules had been followed, the compiler can do whatever it likes. So for objects where the copy constructor and destructor have no side effects, and where no changes are made to the copy, or the original object isn't accessed afterwards (so no one will notice if we make changes to the object), the compiler could prove that eliminating the copy is legal under the "as-if" rule.
But other than that, no, it can't just eliminate the copy, as @Ben said. The "regular" copy elision rules don't cover this case.
Upvotes: 3
Reputation: 283971
I'm fairly sure it cannot.
Even if the outer function no longer explicitly uses the variable, moving the variable would change the semantics of destruction.
Having move constructors for Image
doesn't help, a vector
can move
or swap
without moving its elements.
If the variable is read-only from this point forward, why not capture by reference? You could even create a const reference and capture that.
If the variable is not read-only, the copy is required. It doesn't matter whether the outer function or the lambda performs the modification, the compiler cannot allow that modification to become visible to the other.
The only difference I see between by-value capture and by-value argument passing is that the capture is named, it cannot be a temporary. So argument passing optimizations applicable to temporaries cannot be used.
Upvotes: 9