Оператор сравнения для std :: vector & lt; T & gt; не может найти оператор сравнения для T

Следующий очень простой код не скомпилируется

#include <vector>
#include <string>namespace Foobar {
struct Test {
std::string f;
std::uint16_t uuid;
};
}

bool operator==(const Foobar::Test& lhs, const Foobar::Test& rhs){
return lhs.f == rhs.f && lhs.uuid == rhs.uuid;
}int main(){

std::vector<Foobar::Test> a;
std::vector<Foobar::Test> b;

if(a==b){

}

return 0;
}

https://godbolt.org/g/zn6UgJ

Не будет компилироваться ни в один из моих компиляторов.

Хотя следующее

#include <vector>
#include <string>namespace Foobar {
struct Test {
std::string f;
std::uint16_t uuid;
};

bool operator==(const Foobar::Test& lhs, const Foobar::Test& rhs){
return lhs.f == rhs.f && lhs.uuid == rhs.uuid;
}
}int main(){

std::vector<Foobar::Test> a;
std::vector<Foobar::Test> b;

if(a==b){

}

return 0;
}

https://godbolt.org/g/o4pc1b

Компилирует просто отлично, что заставляет меня думать std::vector<T> Оператор сравнения выглядит в пространстве имен Tпочему он не учитывает глобальное пространство имен?

12

Решение

Обычный поиск безусловного имени начинает поиск в контексте, где используется имя, и идет вверх по цепочке окружающих областей. Он останавливается в самой вложенной области, содержащей соответствующее имя. Это верно даже в том случае, если найденное таким образом имя позднее будет определено как неподходящее (например, перегрузка функции нежизнеспособна для данного вызова или функция-член недоступна).

Здесь контекст поиска std::operator==(vector, vector)поэтому он начинает искать в пространстве имен std, Есть много перегрузок operator== в пространстве имен stdтаким образом, обычный поиск останавливается там и никогда не достигает глобального пространства имен.

Во втором примере перегрузка обнаруживается в зависимости от аргумента. Этот поиск выполняется специально для имен функций в вызовах функций, в дополнение к неквалифицированному поиску, и ищет имена в областях, связанных с типами аргументов вызова. В примере пространство имен Foobar связан с Foobar::Testи так, зависящий от аргумента поиск ищет это пространство имен и находит Foobar::operator==,

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

8

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector