Opened 9 years ago
Closed 9 years ago
#8571 closed Bugs (invalid)
no free version begin/end for boost::irange
Reported by: | 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 , 9 years ago
comment:2 by , 9 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
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::".
Sorry I forgot to specify my compiler: gcc-4.7.2