Это потому, что зависимый от аргумента поиск (ADL).
Два аргумента вызова compare(first.element, second.element)
имеют тип Value
, поэтому выполняется поиск во всем включающем пространстве имен Value
, т. Е. Глобальном пространстве имен, и перегрузке compare
для Value
найдено.
Если вы замените Value
на базовый тип, например, int
, тогда ADL не будет и код не будет работать:
template<typename T>
class Container
{
public:
Container(T value) : element(value) {}
T element;
};
template<typename T>
int compare(Container<T> const& first, Container<T> const& second)
{
return compare(first.element, second.element); // error: no matching function for call to 'compare(const int&, const int&)'
}
int compare(int first, int second)
{
if (first < second)
return -1;
else if (first > second)
return 1;
return 0;
}
int main()
{
auto l1 = Container<int>(1);
auto l2 = Container<int>(2);
compare(l1, l2);
}