On 29/11/2007, Warren Young <mysqlpp@stripped> wrote:
> Joseph Artsimovich wrote:
> >>> (Should probably define a global
> >>> swap(x, y) to use this member)
> >> Why?
> > I am not the original poster, but I can explain that. The global swap()
> > function is usually created so that template code such as std::sort()
> > would use class-specific swap() implementation, rather than a generic
> > one.
Thanks, Joseph. Swap is now being recognised as an important
operation in C++, and as more classes implement an efficient swap,
more libraries will be written to use swap where possible. If your
class doesn't specialise swap() it will still work correctly by
swapping using a temporary, but it could be faster. In the general
case (not mysql++'s refcounted ptr) the temporary copy might need to
allocate memory which could throw, whereas a swap member can often
give the strong exception-safety guarantee.
For more thoughts on exception-safety via swap:
(that's a longish page, but the exception-safety part is fairly short)
> Ah, this also explains why you'd want member swap() to be public. But
> it begs the question: why would one want to sort a collection of
> refcounted pointers? Is it even appropriate to do so without comparison
> operators that delegate to the pointed-to-type?
It's probably not appropriate often, but that just means that it's
usually done with a custom compatison functor :) you still swap the
smart pointers when sorting the collection.
> I'm not going to do anything about this immediately, so if someone comes
> up with a reason for needing global swap() and thus keeping member
> swap() public, I'm all ears. But if I don't hear anything I like before
> the v3 development effort starts winding up, I'm going to hide member
> swap(). If we discover the need for global swap() after v3 is released
> and can't wait for v4 to break the ABI again, we can make it a friend.
Item 6 - Exceptional C++ Style, Sutter.
Specifically, I would suggest that Row is made swappable, by providing
a global swap(Row&,Row&) function, which delegates to Row::swap(Row&)
which swaps the refcountedptrs, which is very efficient thanks to a
(public or private, doesn't matter) swap member. This means
manipulating Row objects in containers is cheaper.
Swap is a Good Thing, if it doesn't cost you anything or compromise
your design, IMHO it's better to provide it than not.
That said ... it ain't going to break mysql++ to leave it out, so I'll