Boost range and ADL lookup resulting in ambiguous calls

Viewed 120

Please check this reduced example (boost 1.68):

#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/range.hpp>
#include <vector>

void f(std::vector<boost::shared_ptr<int>>& c) {
    using std::advance;
    auto it = c.begin();
    advance(it, 1);
}

This code fails to compile on both gcc-8 and clang-6 with the same error, the call to advance() is ambiguous.

These the two candidates:

candidate: ‘constexpr void std::advance(_InputIterator&, _Distance)
[with _InputIterator =
__gnu_cxx::__normal_iterator<boost::shared_ptr<int>*, std::vector<boost::shared_ptr<int> > >; _Distance = int]’
     advance(_InputIterator& __i, _Distance __n)
candidate: ‘constexpr void boost::iterators::advance_adl_barrier::advance(InputIterator&, Distance) [with InputIterator =
__gnu_cxx::__normal_iterator<boost::shared_ptr<int>*, std::vector<boost::shared_ptr<int> > >; Distance = int]’
         advance(InputIterator& it, Distance n)

The second candidate is introduced by boost::range and unfortunately I cannot simply remove it since it is included by another dependency (boost::geometry).

The unqualified call is performed by another library (range-v3) and it is made as is on purpose to exploit the ADL

This is obviously an ADL related problem, but I miss why the compilers found the second candidate since no boost::range types are involved.

0 Answers
Related