Boost logo

Boost :

From: Rainer Deyke (root_at_[hidden])
Date: 2002-02-07 16:48:23


Some more thoughts on the subject:

Relocate construction is the most fundamental type of move. Relocate
construction can usually be implemented as a bitwise copy. The major
exception is when the object contains a pointer into itself, such as
in virtual inheritance or the obvious implementation of
'std::fstream'. Given that relocate construction is at least as
fundamental as copy construction, it makes sense that the compiler
should automatically generate relocate constructors where possible in
some future version of the language. When all members and bases of a
class define a relocate constructor and a safe copy constructor is
automatically generated, it is always possible to automatically
generate a safe relocate constructor. When all members and bases of a
class define a relocate constructor but the copy constructor is
explicitly declared, it is still usually safe to automatically
generate a relocate constructor, but doing so may break existing code.

A transfer constructor can be implemented in terms of a relocate
constructor and a non-throwing default constructor, although the
result might not be as efficient a manual implementation.

Relocate assignment can be implemented efficiently in terms of
destruction and relocate construction.

A non-throwing swap can be (efficiently) implemented in terms of
relocate construction, and transfer assignment can be implemented in
terms of a non-throwing swap (although possibly not as efficiently as
a manual implementation).

Another useful variation on the theme would be a swap constructor that
leaves the source object in a default-constructed state (as opposed to
the transfer constructor, which leaves the source object in an
indeterminate-but-destructable state). The "copy" constructor of
'std::auto_ptr' is really a swap constructor. A swap constructor can
be feirly efficiently implemented in terms of relocate constructor and
non-throwing default constructor.

Move operations are useful for passing arguments in a function call an
returning values from a function. Whatever syntax is chosen should
accomodate those cases. Passing arguments requires the constructor
forms (relocate, transfer and swap). Returning values is trickier
since the number of objects involved depends on compiler optimization.
Requiring stronger compiler optimization may be more useful than an
explicit syntax here.

Another example of a class that can support relocate construction but
not transfer construction:

  class C {
  public:
    C() { global_resource.lock(); }
    ~C() { global_resource.unlock(); }
  }

Ideally it should be possible to use movable but non-copyable objects
as functions arguments and to store them in containers.

--
Rainer Deyke | root_at_[hidden] | http://rainerdeyke.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk