The template version is used by the compiler to calculate t = max(a, b)
and max(t, c)
. Any quote from the Standard supporting this is welcome.
#include <iostream>
template <typename T>
inline T const& max (T const& a, T const& b)
{
std::cout << "template" << '\n';
return a < b ? b : a;
}
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
return max (max(a,b), c);
}
inline int const& max (int const& a, int const& b)
{
std::cout << "non-template" << '\n';
return a <b ? b : a;
}
int main()
{
std::cout << max(3, 5, 7) << '\n';
}
The code prints
template
template
7
The definition of your non-template version of max()
is not visible at the call-site, it's defined afterwards. Either move that function above the 3-argument max()
or add a prototype above the call-site.
int const& max (int const& a, int const& b);
Now the non-template version is chosen in both cases.
Live example
As for why this is the case, I believe §3.4.1/1 [basic.lookup.unqual] holds the answer.
In all the cases listed in 3.4.1, the scopes are searched for a declaration in the order listed in each of the respective categories; name lookup ends as soon as a declaration is found for the name. If no declaration is found, the program is ill-formed.
Note that argument-dependent name lookup does not apply in your case since the arguments to max
are int
, and not a user defined type. Only unqualified name lookup applies, hence, as quoted above, the lookup stops when the first match (the function template version of max()
) is found.
The last sentence in the quoted section also explains why if you comment out the function template version of max()
your code will not compile.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With