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