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