Меня несколько раз укусила эта проблема, и мои коллеги тоже. При компиляции
#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 (…)
префикс « ::
», но почему это необходимо? В глобальном пространстве имен есть совершенно допустимое совпадение, так зачем вызывать поиск, зависящий от аргумента? Кто-нибудь может объяснить здесь обоснование?