The explicit keyword is recommended for all most constructors which can be called with one argument, except for copy constructors.
For copy constructors, it has an use (to forbid implicit copying via function call, return, etc), but it’s not what’s usually wanted.
What about move constructors? Is there any reasonable use case to make them explicit? What’s the good practice here?
An
explicitmove constructors can affect compatibility with e.g. Standard algorithms. For instance,std::swap<T>requires thatTbe MoveConstructible. In turn, MoveConstructible is specified in terms of an expression, namelyT u = rv;(wherervis an rvalue of typeT).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 withstd::swap. (In this particular instance however it is possible to specializestd::swapto provide the desired functionality, e.g. by usingT u(rv);).Put more simply, an
explicitmove 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:
unique_ptr<T, D>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