::max(47, 11, 33);
на самом деле ::max<int>(47, 11, 33);
, что в свою очередь вызовет ::max<int>(::max<int>(47, 11), 33);
, что может быть удивительно.
Поскольку int
является встроенным (так что ADL отсутствует), max(int, int)
должно быть видно до того, как будет определено max(T, T, T)
, чтобы разрешить вызов этой версии в шаблоне:
С пользовательским типом, благодаря ADL, ваша max
функция может быть объявлена после:
template <typename T>
T max (T a, T b)
{
std::cout << "max<T>()\n";
return b < a ? a : b;
}
// Should be declared **before** max(T, T, T)
int max(int a, int b)
{
std::cout << "max(int,int) \n";
return b < a ? a : b;
}
template<typename T>
T max (T a, T b, T c)
{
return max (max(a,b), c);
}
struct S {};
// Might be declared after max(T, T, T)
S max(S, S)
{
std::cout << "max(S, S)\n";
return {};
}
Теперь и max(0, 1, 2)
, и max(s, s, s)
будут вызывать внутреннюю перегрузку без шаблона.
Demo