|
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