
Isaac Dupree wrote:
(please include some explanatory comments!:-)
Yes, I think you're right, <boost/utility/swap.hpp> deserves some more lines of comment.
// various workarounds to avoid compiler bugs that make the compiler // find boost::swap before std::swap make us // - put this outside the boost namespace, // - use a using-directive rather than a using-declaration, // - and make boost::swap have two template arguments.
Thanks for your input! Quite nice actually, but not yet entirely correct: the using-directive is there to work around some other compiler bugs! Both MSVC 7.1 and Borland didn't do argument-dependent lookup when ::boost_swap_impl::swap_impl had a using-declaration ("using std::swap"). While now they do, due to Joseph's commit [47967] :-) See also the thread, "[boost] [swap] Workaround for ADL failures of MSVC 7.1 and Borland okay?", http://lists.boost.org/Archives/boost/2008/08/140578.php So I've just edited your comments a little bit: // Note: the implementation of the boost::swap utility contains // various workarounds: // - swap_impl is put outside the boost namespace, to avoid infinite // recursion (stack overflow) when swapping objects of a primitive type. // - swap_impl has a using-directive, rather than a using-declaration, // because some compilers (including MSVC 7.1 and Borland 5.9.3) don't // do argument-dependent lookup when it has a using-declaration instead. // - boost::swap has two template arguments, instead of one, to // avoid ambiguity when swapping objects of a Boost type that does // not have its own boost::swap overload. Okay? I wouldn't mind adding it to utility/swap.hpp, and committing it to the trunk.
Although I couldn't say how strong the use-case is; probably it's rarely if ever a good idea to specify *that* template argument explicitly.
Okay. I'm not sure if my swap<animal_base_class>(cat,dog) use-case is very strong either. So as long as nobody really feels the need to have direct access to ::boost_swap_impl::swap_impl, I wouldn't mind leaving it outside of the boost namespace.
The function name already confuses me a little though: why should a function named boost::swap do ADL when the nearly equivalent name std::swap doesn't?
Because of its name, the boost::swap utility is overloaded by swap functions from other Boost libraries. And of course, when boost::swap is called for a type that has its own boost::swap overload, this overload will be called directly. Isn't that nice? :-) By the way, boost::exception is also quite different from std::exception. Even more so!
The name swap_using_adl, besides that not everyone knows the acronym "adl", makes it less obvious whether it can find the generic std::swap implementation (through 'using' not ADL).
Indeed, you're right. I was actually considering to spell it out: swap_using_argument_dependent_lookup(T&,T&). But do you have a better suggestion? What about just renaming the function to "call_swap(T&,T&)"? Because that's what it does: it just calls the most appropriate swap function. Anyway, its name is not that important, as long as the helper function remains an "implementation detail".
But maybe the main function has to be named boost::swap to convince clueless people to use it instead of std::swap...
Hope you're convinced already... Kind regards, Niels