Boost logo

Boost :

From: Hamish Mackenzie (boost_at_[hidden])
Date: 2002-02-05 16:28:34


On Tue, 2002-02-05 at 20:46, Howard Hinnant wrote:
> While I thought auto_vector might be a good place to explore move
> semantics, I see no reason that auto_vector should come to a standstill
> while move semantics are worked out. But that appears to have
> happened. Thus the new thread dedicated to move...
>
> On Tuesday, February 5, 2002, at 02:52 PM, Hamish Mackenzie wrote:
>
> > template< class T >
> > void move_construct( T *destination, T &source )
> > {
> > using namespace std;
> > construct( destination );
> > move( *destination, source ); // as per previous post
> > }
>
> I'm a little concerned that this might require T to be default
> constructible. I don't think we want to have move_construct require
> that. But maybe I'm just misreading pseudo code.

No you are not misreading. And it was not intended to be "pseodo"
code. Although I don't have a copy of the standard and the sgi
documentation does not seem to include the version of std:::construct
that takes one argument (though it is in gcc 3).

This would only be the default behavior though. It would require

1) T::T() ( or construct( T * ) )
2) move( T &, T & ) (assignment move)

In order for move_construct to be no-throw it would also require both of
these to be no-throw.

The default move( T &, T & ) would be implemented using swap (which in
most cases is no throw). For scalar types it would use assignment.

If you don't want a default constructor you will have to do one of the
following.

1) You could add a private constructor and make boost::move_construct a
friend.

2) You could implement move_construct for your class

For instance a common situation might be :

class my_class
{
  int x_;
public:
  my_class( const my_class & m ) : x_( m.x_ ) {}
  friend void move_construct( my_class *, my_class & );
};

void move_construct( my_class *destination, my_class & source )
{
  std::construct( destination, source );
}

The advantage of using the default constructor and swap for implementing
move_construct is that its performance will be much better if copying
the class requires memory to be allocated. It also is normaly easier to
write no-throw swap and default constructor than it is to write no-throw
copy.

> Also I'm not clear how a given class would plug into move_construct
> (provide its move semantics). Could you expound on that?

Does the example above make sense?

In order for the Koenig lookup to work users of move_construct would
call it like so :

using boost::move_construct;
move_construct( x, y );

It might be better to put these functions into a move_traits class to
allow the use of partial specialization.
 
Hamish Mackenzie


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