Search code examples
c++lambdashared-ptr

Capturing shared_ptr in lambda using std::move


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


Solution

  • 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)).