
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