On Mon, Dec 27, 2010 at 4:25 AM, Nathan Ridge <zeratul976@hotmail.com> wrote:

The following code fails to compile with a development build of gcc 4.6:

#include <boost/range/adaptor/reversed.hpp>
#include <vector>
int main()
{
   std::vector<int> v;
   for (int i : v | boost::adaptors::reversed);
   return 0;
}

The errors are:

reversed.cpp: In function âint main()â:
reversed.cpp:16:39: error: call of overloaded âbegin(boost::range_detail::reverse_range<std::vector<int> >&)â is ambiguous
reversed.cpp:16:39: note: candidates are:
/usr/local/lib/gcc/i686-pc-linux-gnu/4.6.0/../../../../include/c++/4.6.0/bits/range_access.h:56:5: note: decltype (__cont->begin()) std::begin(const _Container&) [with _Container = boost::range_detail::reverse_range<std::vector<int> >, decltype (__cont->begin()) = boost::reverse_iterator<__gnu_cxx::__normal_iterator<int*, std::vector<int> > >]
/usr/local/lib/gcc/i686-pc-linux-gnu/4.6.0/../../../../include/c++/4.6.0/bits/range_access.h:46:5: note: decltype (__cont->begin()) std::begin(_Container&) [with _Container = boost::range_detail::reverse_range<std::vector<int> >, decltype (__cont->begin()) = boost::reverse_iterator<__gnu_cxx::__normal_iterator<int*, std::vector<int> > >]
/home/nridge/lib/boost/boost/range/begin.hpp:107:61: note: typename boost::range_iterator<const T>::type boost::begin(const T&) [with T = boost::range_detail::reverse_range<std::vector<int> >, typename boost::range_iterator<const T>::type = boost::reverse_iterator<__gnu_cxx::__normal_iterator<int*, std::vector<int> > >]
/home/nridge/lib/boost/boost/range/begin.hpp:96:55: note: typename boost::range_iterator<C>::type boost::begin(T&) [with T = boost::range_detail::reverse_range<std::vector<int> >, typename boost::range_iterator<C>::type = boost::reverse_iterator<__gnu_cxx::__normal_iterator<int*, std::vector<int> > >]
reversed.cpp:16:39: error: call of overloaded âend(boost::range_detail::reverse_range<std::vector<int> >&)â is ambiguous
reversed.cpp:16:39: note: candidates are:
/usr/local/lib/gcc/i686-pc-linux-gnu/4.6.0/../../../../include/c++/4.6.0/bits/range_access.h:76:5: note: decltype (__cont->end()) std::end(const _Container&) [with _Container = boost::range_detail::reverse_range<std::vector<int> >, decltype (__cont->end()) = boost::reverse_iterator<__gnu_cxx::__normal_iterator<int*, std::vector<int> > >]
/usr/local/lib/gcc/i686-pc-linux-gnu/4.6.0/../../../../include/c++/4.6.0/bits/range_access.h:66:5: note: decltype (__cont->end()) std::end(_Container&) [with _Container = boost::range_detail::reverse_range<std::vector<int> >, decltype (__cont->end()) = boost::reverse_iterator<__gnu_cxx::__normal_iterator<int*, std::vector<int> > >]
/home/nridge/lib/boost/boost/range/end.hpp:103:61: note: typename boost::range_iterator<const T>::type boost::end(const T&) [with T = boost::range_detail::reverse_range<std::vector<int> >, typename boost::range_iterator<const T>::type = boost::reverse_iterator<__gnu_cxx::__normal_iterator<int*, std::vector<int> > >]
/home/nridge/lib/boost/boost/range/end.hpp:92:55: note: typename boost::range_iterator<C>::type boost::end(T&) [with T = boost::range_detail::reverse_range<std::vector<int> >, typename boost::range_iterator<C>::type = boost::reverse_iterator<__gnu_cxx::__normal_iterator<int*, std::vector<int> > >]

The problem is caused by an ambiguity between std::begin/end (new in C++0x) and boost::begin/end.


I don't believe that it should be ambiguous since all of the calls to begin/end are qualified. See the relevant code:

            explicit reversed_range( R& r )
                : base( iterator(boost::end(r)), iterator(boost::begin(r)) )
                                      ^^^^^^^^^^^^^^^              ^^^^^^^^^^^^^^^^^
            { }

Hence the error reporting that this is ambiguous with std::begin/std::end is likely a defect in either compiler lookup or a missing qualified call to begin/end in the standard library.

I've found this bug: https://svn.boost.org/trac/boost/ticket/4099
and this thread: http://groups.google.com/group/boost-devel-archive/browse_thread/thread/f97ab9c132ec590b/457aa0a5e165fab9?lnk=raot#457aa0a5e165fab9


This ticket is somewhat different. Boost.Algorithm was not qualifying the calls to begin/end and hence with argument dependent lookup there was ambiguity.
 
which mention similar issues, but neither of them seem to address/fix the issue in Boost.Range.


There have not been any issues with missing qualification of begin/end calls in Boost.Range hence no ticket.
 
Regards,
Nate.

You might get a quicker response from the GCC team, but I'm happy to look into this issue if you provide the exact version of GCC and library version you are using. It will, of course, take me a while since I'll have to setup the compiler and environment.

You might want to take a look at the relevant standard library, or the compiler implementation of the new 'for' syntax. I suspect there might be an unqualified call to begin() and/or end().

Regards,
Neil Groves