Explicit move constructor?

An explicit move constructors can affect compatibility with e.g. Standard algorithms. For instance, std::swap<T> requires that T be MoveConstructible. In turn, MoveConstructible is specified in terms of an expression, namely T u = rv; (where rv is an rvalue of type T).

If there is neither a non-explicit copy constructor nor a non-explicit move constructor for a given type then T u = rv; is invalid and that type can’t be used with std::swap. (In this particular instance however it is possible to specialize std::swap to provide the desired functionality, e.g. by using T u(rv);).

Put more simply, an explicit move or copy constructor defies expectations and can’t be used as well with generic code.

Some other parts of the Standard library that put a MoveConstructible requirement:

  • the deleter of unique_ptr<T, D>
  • call wrappers, used in e.g. bind (all the decayed types that are passed are concerned)
  • thread, async, call_once (all specified in terms of call wrappers)
  • sort, stable_sort, nth_element, sort_heap

Leave a Comment