[STL]
void f(int) { puts("Standard two-phase!"); } template <typename T> void g(T t) { f(t); } void f(double) { puts("Microsoft one-phase!"); }
[Billy O'Neal]
It is "better" as in it is "what the standard says".
Yes.
In g, f is not a dependent name.
Incorrect. f is a dependent name, because which f is selected depends on what T is. But two-phase isn't as simple as "look up non-dependent names immediately, look up dependent names late". The relevant Standardese is N4594 14.6.4 [temp.dep.res]/1: "In resolving dependent names, names from the following sources are considered: (1.1) - Declarations that are visible at the point of definition of the template. (1.2) - 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." Here, 1.1 means that f(int) is visible when g() is defined, while f(double) has not yet been seen. 1.2 has the ability to see things that are declared after g()'s definition, BUT it is restricted to "associated namespaces" (like what's considered for ADL). Here, 3.14 is a double and has no associated namespaces, so nothing extra is considered. (It took me a long time to understand these rules, and I still don't have a very good intuition for them.) STL