Boost logo

Boost :

From: Joe Gottman (joegottman_at_[hidden])
Date: 2001-01-21 22:02:46


----- Original Message -----
From: "Dean Sturtevant" <deansturtevant_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Sunday, January 21, 2001 9:27 PM
Subject: [boost] Re: Optimising assignment using std::swap

> I find it hard to imagine a case where std::swap is more efficient
> than assignment, unless the assignment is coded inefficiently. Can
> you provide an example where that might not be the case?

    I don't know about being more efficient, but std::swap might be
preferable to strict assignment for exception-safety reasons. (See Herb
Sutter's book _Exceptional C++_ .) For instance, suppose you have the
following class:

class Foo {
   std::string s1;
   std::string s2;
public:
...
    Foo(const Foo&rhs); // Copy constructor
    Foo &operator=(const Foo &rhs); //Assignment
};

The naive way of implementing operator= () looks

Foo &operator=(const Foo &rhs);
{
        s1 = rhs.s1;
        s2 = rhs.s2;
        return *this;
}

The problem is what happens if the second assignment throws. Then the first
assignment has taken place successfully, but the second one has not. This
puts the object into an inconsistent state, halfway between its original
state and the desired new state. Some class invariants may no longer be
valid, for instance if s1 is supposed to always be shorter than s2.

On the other hand, if operator= is written as follows:

Foo &operator=(const Foo &rhs)
{
    Foo temp(rhs); // Might throw
    s1.swap(rhs.s1); // Won't throw
    s2.swap(rhs.s2); // Won't throw
    return *this;
}

This is guaranteed to either work or leave the left hand side of the
assignment completely unchanged, since string::swap() just exchanges a few
pointers and cannot throw.

Joe Gottman.


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