Неоднозначный вызов шаблонной функции из-за ADL

Меня несколько раз укусила эта проблема, и мои коллеги тоже. При компиляции

#include <deque>
#include <boost/algorithm/string/find.hpp>
#include <boost/operators.hpp>

template< class Rng, class T >    
typename boost::range_iterator<Rng>::type find( Rng& rng, T const& t ) {
      return std::find( boost::begin(rng), boost::end(rng), t );
}

struct STest {
      bool operator==(STest const& test) const { return true; }
};

struct STest2 : boost::equality_comparable<STest2>   {
      bool operator==(STest2 const& test) const { return true; }
};

void main() {
      std::deque<STest> deq;
      find( deq, STest() ); // works
      find( deq, STest2() ); // C2668: 'find' : ambiguous call to overloaded function
}

... компилятор VS9 дает сбой при компиляции второй находки. Это связано с тем, что STest2 наследуется от типа, определенного в пространстве имен boost, который запускает компилятор, чтобы попробовать ADL, который находит boost :: algorithm :: find (RangeT & Input, const FinderT & Finder ) .

Очевидное решение - поставить перед вызовом find (…) префикс « :: », но почему это необходимо? В глобальном пространстве имен есть совершенно допустимое совпадение, так зачем вызывать поиск, зависящий от аргумента? Кто-нибудь может объяснить здесь обоснование?

7
задан uSeRnAmEhAhAhAhAhA 6 August 2013 в 19:23
поделиться