Ответ 1
Обычный неквалифицированный поиск имени начинает искать в контексте, где используется имя, и поднимает цепочку охватывающих областей. Он останавливается в самой вложенной области, содержащей совпадающее имя. Это верно, даже если имя, найденное таким образом, позднее определяется как неподходящее (например, функция перегрузки является нежизнеспособной для данного вызова или функция-член недоступна).
Здесь контекст поиска - std::operator==(vector, vector)
, поэтому он начинает искать в пространстве имен std
. Существует много перегрузок operator==
в пространстве имен std
, поэтому обычный поиск останавливается и никогда не достигает глобального пространства имен.
Во втором примере перегрузка найдена с помощью зависящего от аргумента поиска. Этот поиск выполняется специально для имен функций в вызовах функций, в дополнение к неквалифицированному поиску, и ищет имена в областях, связанных с типами аргументов вызова. В примере пространство имен Foobar
связано с Foobar::Test
, и поэтому зависящий от аргумента поиск ищет это пространство имен и находит Foobar::operator==
.
По этой причине свободные функции, которые логически являются частью открытого интерфейса класса, например перегруженные операторы, обычно должны быть определены в том же пространстве имен, что и сам класс, чтобы дать возможность зависящим от аргумента поиска работать. std::operator==(vector, vector)
является хорошим примером этого: a==b
в вашем примере работает в зависимости от зависимого от аргумента поиска.