
1) Would it be a good idea (aside from breaking backwards compatibility) to insulate boost::swap from being found via ADL? Consider another library, tsoob, which also has a swap intended to be used in the same manner as boost::swap (i.e., it finds a free function swap via ADL, falling back to std::swap or maybe some custom swap or whatever). Now tsoob::swap and boost::swap cannot be used in the same program (ambiguous call to overloaded function swap) if the associated namespaces of the type being swapped includes both boost and tsoob (certainly possible). What I'm thinking about is the possibility of creating a namespace boost::adl which contains (what would have previously been called) boost::swap, as well as any other similar free functions. So the only way to invoke boost::adl::swap is to make it explicit; it will never be found via ADL. Plus it helps document the underlying mechanism (ADL) of boost::swap. 2) Is there some way for boost::swap and tsoob::swap to coexist peacefully while retaining backwards compatibility for both? - Jeff

I Googled for tsoob, but couldnt' find any references to it. It would be helpful to have a look at tsoob::swap to see what's causing the ambiguity and how/if it could be resolved. Also, I always intended for boost::swap to be called explicitly, rather than though ADL - it's supposed to hise the use of ADL from the user (no need for 'using std::swap' etc). If you use a fully qualified call, is there still ambiguity between boost and tsoob?

Joseph Gauterin wrote:
I Googled for tsoob, but couldnt' find any references to it. It would be helpful to have a look at tsoob::swap to see what's causing the ambiguity and how/if it could be resolved.
Also, I always intended for boost::swap to be called explicitly, rather than though ADL - it's supposed to hise the use of ADL from the user (no need for 'using std::swap' etc). If you use a fully qualified call, is there still ambiguity between boost and tsoob?
Of course, tsoob is just a made-up name... Upon further reflection, this is probably something that shouldn't happen, as it depends on the user wanting to use their own fallback swap function rather than std::swap. I was (however rightly or wrongly) concerned with code that does something like the following: -------- BEGIN CODE -------- #include <algorithm> // for std::swap #include <boost/utility/swap.hpp> namespace std { struct X; } namespace boost { struct Y; } namespace tsoob { namespace no_adl { #if 0 // Enabling this one gives ambiguities with std::swap template< class T > void swap(T& x1, T& x2) { /* fallback custom generic swap */ throw 0; } #endif #if 0 // Enabling this one gives ambiguities with boost::swap template< class T1, class T2 > void swap(T1& x1, T2& x2) { /* fallback custom generic swap */ throw 0; } #endif } } // namespace no_adl / namespace tsoob namespace tsoob_swap_impl { template< class T > void swap_impl(T& x1, T& x2) { using namespace ::tsoob::no_adl; swap(x1, x2); } } // namespace tsoob_swap_impl namespace tsoob { namespace adl { template< class T > void swap(T& x1, T& x2) { ::tsoob_swap_impl::swap_impl(x1, x2); } } // namespace adl template< class T > struct Z { }; } // namespace tsoob int main() { tsoob::Z< std::X > zx1, zx2; tsoob::adl::swap(zx1, zx2); tsoob::Z< boost::Y > zy1, zy2; tsoob::adl::swap(zy1, zy2); } -------- END CODE -------- At the end of the day, this is probably just not a Good Idea. However, I still think it might've been a good idea to insulate boost::swap from being found via ADL at all by inserting another namespace in there (so it's boost::adl::swap) rather than declaring boost::swap to have 2 template parameters to make it less preferred than std::swap. Evidently I can't think of a good example where this is a problem, though :/ Apologies for the noise, - Jeff

Of course tsoob is a made up name - I'm slightly embarrassed not to have noticed!
participants (2)
-
Jeffrey Hellrung
-
Joseph Gauterin