Boost logo

Boost :

From: François Duranleau (duranlef_at_[hidden])
Date: 2007-10-10 12:26:30


Hi!

This is a follow up to:

http://article.gmane.org/gmane.comp.lib.boost.devel/165366

I have been using it since then, but I recently hit a problem when more
than one namespace are associated to a type.

Example:

#include <boost/utility/swap.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>

#include <boost/array.hpp>

int
test_main( int , char*[] )
{
     // boost::array or anything in boost such that pair_type has std and
     // boost as associated namespaces
     typedef ::std::pair< ::boost::array< int , 1 > , int > pair_type ;
     pair_type p1 ;
     pair_type p2 ;

     p1.first[ 0 ] = p1.second = 0 ;
     p2.first[ 0 ] = p2.second = 1 ;

     ::boost::swap( p1 , p2 ) ;

     // whatever here, it doesn't matter
     BOOST_CHECK_EQUAL( p2.first[ 0 ] , 0 ) ;
     BOOST_CHECK_EQUAL( p2.second , 0 ) ;
     BOOST_CHECK_EQUAL( p1.first[ 0 ] , 1 ) ;
     BOOST_CHECK_EQUAL( p1.second , 1 ) ;

     return 0 ;
}

//-----------------------------------------------------------------

Compiling this results in an ambiguity in the call of overloaded swap (at
least, with gcc-4.0.2 and gcc-4.2.0):

../../../../boost/utility/swap.hpp: In function 'void boost_swap_impl::swap_impl(T&, T&) [with T = std::pair<boost::array<int,
1ul>, int>]':
../../../../boost/utility/swap.hpp:31: instantiated from 'void boost::swap_adl_barrier::swap(T&, T&) [with T = test_main(int,
char**)::pair_type]'
std_and_boost.cpp:17: instantiated from here
../../../../boost/utility/swap.hpp:20: error: call of overloaded 'swap(std::pair<boost::array<int, 1ul>, int>&, std::pair<boost::array<int,
1ul>, int>&)' is ambiguous
/usr/lib/gcc/x86_64-redhat-linux/4.0.2/../../../../include/c++/4.0.2/bits/stl_algobase.h:92: note: candidates are: void std::swap(_Tp&, _Tp&) [with _Tp =
std::pair<boost::array<int, 1ul>, int>]
../../../../boost/utility/swap.hpp:29: note: void boost::swap_adl_barrier::swap(T&, T&) [with T = test_main(int,
char**)::pair_type]

I tried to move boost::swap_adl_barrier::swap to
boost_swap_adl_barrier::swap, but I still got the same error. I find it
strange because I thought that 'using' directives were ignored for ADL. I
also tried to write in namespace boost "using namespace
boost_swap_adl_barrier;", but then the compiler complains that boost::swap
is not found. So, is it a compiler bug, an ADL limitation, or is there a
solution?

For reference, here is the content of boost/utility/swap.hpp (stripped
down a little):

// Copyright (C) 2007 Steven Watanabe, Joseph Gauterin

#include <algorithm> //for std::swap

namespace boost_swap_impl
{
   template<class T>
   void swap_impl(T& left, T& right)
   {
     using std::swap;//use std::swap if argument dependent lookup fails
     swap(left,right);
   }
}

namespace boost
{
   namespace swap_adl_barrier
   {
     template<class T>
     void swap(T& left, T& right)
     {
       ::boost_swap_impl::swap_impl(left, right);
     }
   }

   using swap_adl_barrier::swap;
}

-- 
Francois Duranleau

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