From: Howard Hinnant on
On Jun 18, 11:30 am, "Martin B." <0xCDCDC...(a)gmx.at> wrote:
> That's why I pointed out that return-by-value may be more
> expensive that other alternatives when doing an assignment instead of
> initialization. (I do think it does not really matter with C++0x move
> semantics, because this is also applied when assigning?)

Answer to the last bit about C++0X:

Short answer:

Most of the time it won't matter.

obj = fn();

The rvo/move construct out of fn() will be O(1) (whether or not the
compiler implements the rvo). If obj is a standard container and is
not empty(), it first needs to do a clear() which is O(N). However,
most of the time you are move assigning into a value, the logic of the
code is such that obj has already been moved from, and so is already
empty(). In this common case the move assignment into obj will also
be O(1) (making the entire process O(1) - very fast! :-)).

Long answer:

There is a new allocator design in town which is far more powerful and
flexible than our C++03 allocators. It will correctly handle state-
ful allocators, as long as you tweak the right knobs for your special
allocator.

One of the knobs is a nested (but optional) const type in the
allocator called:

propagate_on_container_move_assignment::value

(either std::true_type or std::false_type)

When this type is std::false_type, and when the allocator state of the
lhs and rhs side of the move assignment are not equal, then an O(1)
move assignment isn't possible even when the lhs is empty. In this
case container resources can not be transferred from the rhs to the
lhs. So obj has to allocate its own resources and move assign each
individual element of the rhs to the lhs.

The default allocator (std::allocator) has a defaulted
propagate_on_container_move_assignment which evaluates to false_type.
However std::allocators always compare equal. This means that for
std::containers using std::allocator, the std::allocator can never be
transferred under move assignment, but the move assignment can still
transfer memory resources from the rhs to the lhs (do the pointer swap
dance), resulting in an O(1) move assignment when lhs.empty().

-Howard


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]