Consider the following code:
#include <iostream>
template<typename T>
void f(T t)
{
  (void)t;
  std::cout << "templated f(T)\n";
}
template<typename T>
void entry(T t)
{
  f(t);
}
void f(double d)
{
  (void)d;
  std::cout << "normal f(double)\n";
}
int main()
{
  double d = 0.0;
  entry(d);
  return 0;
}
Output:
templated f(T)
I find this surprising, because I thought that the plain function will be selected over any templated version. Why does this happen?
Another thing I noticed while playing around is that: if I put the normal function void f(double) before the templated void entry(T) function the code will call the normal function, basically outputting:
normal f(double)
Therefore my other question: why does the order matter in this particular example?
f is a dependent name, since it depends on t whose type is a template parameter. The name lookup rules for dependent names are given in [temp.dep.res]/1:
In resolving dependent names, names from the following sources are considered:
- Declarations that are visible at the point of definition of the template.
 - Declarations from namespaces associated with the types of the function arguments both from the instantiation context (14.6.4.1) and from the definition context.
 
In other words, normally name lookup inside a template only finds names that have been declared before the template definition (which is not that surprising, since it's the same as for non-templates). The second bullet point allows names declared after the template definition to be found, but only when ADL occurs. This won't be the case when the argument is a fundamental type such as double.
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