In following code std::move
in lambda capture list felt unnecessary to me, but compiler does seem to need it.
As there is extra code for copying shared_ptr is generated if I don't use std::move
.
Question is, why compiler can't optimise this on its own.
template<typename T>
std::function<void(void)> prepLambdaImpl(std::shared_ptr<T> aptr) {
#ifdef CONVERT_SHARED_PTR_TO_XVALUE
return [aptr=std::move(aptr)]
#else
return [aptr]
#endif
{
printf("use count: %ld\n", aptr.use_count());
};
}
Working example: https://godbolt.org/z/W3oWEjsjK
Automatic move only happens in return statement in some specific circumstances, which are not met here.
Last usage doesn't trigger a move instead of a copy.
The as-if rule allows optimization as long than observable behaviour is unchanged. Whereas we know the 2 forms are equivalent, it is not easy to know. Especially move and copy are unrelated functions; so optimizers only uses the copy code to try to optimize it (and it probably misses some extra information as invariant of the class (as refcounter not 0 at start of function)).