From: Sean Parent (sparent_at_[hidden])
Date: 2002-02-06 15:56:59
on 2/5/02 4:40 PM, Howard Hinnant at hinnant_at_[hidden] wrote:
> I think I misstated my goal. I'm hoping that containers will be able to
> detect and use move semantics as an internal optimization, not effecting
> the container's interface.
Sorry - I had viewed this as a splinter to the thread on doing an
auto_ptr_vector, which I had suggested become generalized to support any
object that doesn't support copy semantics but does support some combination
of move / swap.
It was correctly pointed out, that swap can be implemented using
constructing moves (in the same way it is done with copying, through a
temp). But in the case of a non-POD class, I don't think this is a win
unless you define the source from the move to have been destructed as a
result of the move (call this relocate).
The move vs. relocate semantics would be:
move - moving a source A into uninitialized memory B. The result leaves A in
an indeterminate but destructible state. "Copy" construction of an auto_ptr
is an example.
relocate - moving a source A into uninitialized memory B. The result leaves
A in a destructed state. Requires the source A is also managed with
placement new and delete.
The relocate construct would be useful for container optimization - but I
think the complexities of implementing it for anything that can't be treated
as a POD (just do a memcopy for the relocate) is difficult. It may be worth
having a trait though for objects that can use memcopy to relocate.
The first item, I think is simplest to implement using a non-throwing
constructor (one that constructs an object upon which the only valid
operation is destruction) and a swap. That's not to say that this is how you
would have to implement it- however there are many existing classes that
would meet these requirements. So let's define move as:
template <class T>
T* safe_construct(void* placement) throw()
template <class T>
T* move(void* placement, T& x) throw()
T* result (safe_construct<T>(placement));
Specializations can be provided for either safe construction and/or move and
an is_movable trait can be added to the trait library. For items that are
movable, I think you can change the exception guarantee from basic to
transactional without a performance penalty in the non-exception case in the
std containers (assuming they are re-implemented of course). You can also
build containers (or provide an extended interface to the existing
containers) for types that only support move and not copy operations (like
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk