Kos
Kos

Reputation: 72281

Explicit move constructor?

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 a 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?

Upvotes: 33

Views: 7838

Answers (5)

Lingxi
Lingxi

Reputation: 14987

When returning by value from a function, an implicit move constructor can usually make the process more efficient.

Upvotes: 0

Gene Bushuyev
Gene Bushuyev

Reputation: 5538

The actual question is how explicit move constructor could possibly be used? It wouldn't be able to be invoked on rvalues, so compiler would have to always select a copy constructor, if available, or fail to compile.

Edit: here is the link to example: http://www.ideone.com/nm7KM

Upvotes: 3

Bo Persson
Bo Persson

Reputation: 92301

The explicit keyword is recommended for (single argument) converting constructors, to avoid surprising conversions in unexpected places.

Copy constructors and move constructors are hardly "surprising" in that sense. They happen largely where expected. If you don't want them, I would expect them to be marked =delete rather than made explicit.

Upvotes: 7

Luc Danton
Luc Danton

Reputation: 35449

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

Upvotes: 30

Puppy
Puppy

Reputation: 146968

You probably want an implicit move constructor for the majority of uses. They generally fall into the same categories as copy constructors. Explicit isn't recommended for all one-argument constructors, but it is recommended for most. Move constructors are not on that list.

Upvotes: 7

Related Questions