Boost logo

Boost :

From: Niels Dekker - mail address until 2008-12-31 (nd_mail_address_valid_until_2008-12-31_at_[hidden])
Date: 2008-04-27 07:40:34


On Saturday, 12 April, I suggested adding a swap member function to
optional<T>:
>
> optional<T>::swap could be implemented very easily:
>
> void swap( optional & arg )
> {
> using std::swap;
> swap(*this, arg);
> }
>
> By default, it would call the original
> boost::swap(optional<T>&, optional<T>&), by appying ADL.

Fernando (the owner of Boost.Optional) has agreed, so I added the member
function last Friday (trunk, changeset [44766]). Unfortunately some of
the tests I added fail on previous versions of GCC (3.3.1, 3.4, 4.0.1):
http://www.boost.org/development/tests/trunk/developer/optional_.html
Apparently those compilers didn't apply ADL, and called std::swap
instead!

Luckily I have some ideas on how to fix it :-) First of all, when the
compiler was processing the swap member function, it might not have seen
optional<T>'s overload of boost::swap yet. Because
boost::swap(optional<T>&, optional<T>&) was defined a few hundred lines
/after/ the member function. Is the compiler allowed to ignore the
overloaded boost::swap function (template) in this case, when applying
ADL?

Anyway, it's certainly helpful to those compilers to add a forward
declaration:

  namespace boost {
  template<class T> void swap ( optional<T>& , optional<T>& ) ;
  }

It looks like the forward file, "optional_fwd.hpp", is a proper place
for such a forward declaration. Don't you think?

Still this doesn't seem enough to get my copy of GCC (version 3.4.4,
cygming special) to do ADL. It keeps calling std::swap! So instead of
doing "using std::swap", I consider doing "using boost::swap":

    void swap( optional & arg )
      {
        // allow for Koenig lookup
        using boost::swap ;
        swap(*this, arg);
      }

In this particular case I guess, according to the Standard, there
wouldn't be a semantic difference between "using boost::swap" and "using
std::swap" anyway. Right?

Note that optional's swap member function is still an "undocumented
feature" (trunk only). When the tests are passed, I'll add a few lines
of doc.

Frank Mori Hess:
> Maybe it was just my compiler, but I've had problems in the past with
> member swap functions breaking ADL for swap used inside the class. IIRC,
> it would find the member swap function and stop there, never doing ADL.

Peter Dimov wrote:
> This is standard-conforming. You've forgotten the using std::swap
> declaration which reenables ADL by making a nonmember visible in the current
> scope.

Thanks! Luckily none of the tested compilers failed to /compile/ the
member function, so "using std::swap" has certainly succeeded to make a
nonmember swap visible in the scope of the member function definition.
:-)

Kind regards, Niels


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