Boost logo

Boost Users :

Subject: Re: [Boost-users] ambiguity between std::begin/end and boost::begin/end in gcc 4.6
From: Neil Groves (neil_at_[hidden])
Date: 2010-12-27 08:44:28


On Mon, Dec 27, 2010 at 4:25 AM, Nathan Ridge <zeratul976_at_[hidden]>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



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net