Opened 9 years ago

Closed 9 years ago

#8571 closed Bugs (invalid)

no free version begin/end for boost::irange

Reported by: record.nctu.cis91@… Owned by: Neil Groves
Milestone: To Be Determined Component: range
Version: Boost 1.53.0 Severity: Problem
Keywords: Cc:

Description

With the following code, compiler will complain that no begin/end is found for "range_2" which is integer range.
I guess that integer range is missing ADL compatibility ?

#include <vector>

#include <boost/range/iterator_range.hpp>
#include <boost/range/irange.hpp>

int main() {
    std::vector<int> v;

    auto range_1 = boost::make_iterator_range(v);
    auto range_2 = boost::irange(0, 1); 

    begin(range_1); // found by ADL
      end(range_1); // found by ADL
    begin(range_2); // not found by ADL
      end(range_2); // not found by ADL

    return 0;
}

Change History (2)

comment:1 by record.nctu.cis91@…, 9 years ago

Sorry I forgot to specify my compiler: gcc-4.7.2

comment:2 by Nathan Ridge, 9 years ago

Resolution: invalid
Status: newclosed

boost::begin() and boost::end() are not meant to be found by ADL. In fact, Boost.Range specifically takes precautions to prevent boost::begin() and boost::end() from being found by ADL, by declaring them in the namespace boost::range_adl_barrier and then exporting them into the namespace boost from there. (This technique is called an "ADL barrier").

In the case of your range_1, the reason unqualified begin() and end() calls work is because ADL looks not only at the namespace a template was declared in, but the namespaces the template arguments were declared in as well. In this case, the type of range_1 is boost::iterator_range<std::vector<int>::iterator>. The template argument is in namespace std (on most implementations), so ADL finds std::begin() and std::end() (which, unlike boost::begin() and boost::end(), do not use an ADL barrier to prevent being found by ADL).

To get your code to compile, simply add "using boost::begin;" and "using boost::end;", or explicitly qualify your begin()/end() calls with "boost::".

Note: See TracTickets for help on using tickets.