In the following snippet of code, I’ve overloaded the operator== to compare my pair type with string. But for some reason, the compiler isn’t finding my operator as a match for the find function. Why not?
Edit: Thanks for all the suggestions for alternatives, but I’d still like to understand why. The code looks like it should work; I’d like to know why it doesn’t.
#include <vector>
#include <utility>
#include <string>
#include <algorithm>
typedef std::pair<std::string, int> RegPair;
typedef std::vector<RegPair> RegPairSeq;
bool operator== (const RegPair& lhs, const std::string& rhs)
{
return lhs.first == rhs;
}
int main()
{
RegPairSeq sequence;
std::string foo("foo");
// stuff that's not important
std::find(sequence.begin(), sequence.end(), foo);
// g++: error: no match for 'operator==' in '__first. __gnu_cxx::__normal_iterator<_Iterator, _Container>::operator* [with _Iterator = std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>*, _Container = std::vector<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > >]() == __val'
// clang++: error: invalid operands to binary expression ('std::pair<std::basic_string<char>, int>' and 'std::basic_string<char> const')
}
The problem is that
std::findis a function template and it uses argument-dependent lookup (ADL) to find the rightoperator==to use.Both of the arguments are in the
stdnamespace (std::pair<std::string, int>andstd::string), so ADL starts by looking in thestdnamespace. There it finds someoperator==(which one, it doesn’t matter; there are lots in the Standard Library and if you’ve included<string>, at least the one that compares twostd::basic_string<T>objects could be found).Because an
operator==overload is found in thestdnamespace, ADL stops searching enclosing scopes. Your overload, which is located in the global namespace, is never found. Name lookup occurs before overload resolution; it doesn’t matter during name lookup whether the arguments match.