Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 870
Kos Avatar asked Jul 20 '11 07:07

Kos


People also ask

Should move constructor be explicit?

Explicit isn't recommended for all one-argument constructors, but it is recommended for most. Move constructors are not on that list.

What does implicit move constructor do?

Implicitly-defined move constructor For non-union class types (class and struct), the move constructor performs full member-wise move of the object's bases and non-static members, in their initialization order, using direct initialization with an xvalue argument.

What is the move constructor?

A move constructor allows the resources owned by an rvalue object to be moved into an lvalue without creating its copy. An rvalue is an expression that does not have any memory address, and an lvalue is an expression with a memory address.

Where is the move constructor used?

A move constructor enables the resources owned by an rvalue object to be moved into an lvalue without copying. For more information about move semantics, see Rvalue Reference Declarator: &&. This topic builds upon the following C++ class, MemoryBlock , which manages a memory buffer.


Video Answer


2 Answers

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
like image 97
Luc Danton Avatar answered Sep 21 '22 23:09

Luc Danton


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.

like image 41
Puppy Avatar answered Sep 22 '22 23:09

Puppy