OK, since the earlier prints are in error, I'll post what's in the 15th printing and explain the issue. Please note, however, that the example as given is
still incorrect. (WTH was Stroustrup thinking when he wrote this?)
C.13.8.3 says:
OK, so I pointed out that the comment is wrong. The line invokes f<int>(2), not f<X>(X(2)). However, that's not the point anyway.
The point is that f<int>(2) in turn does not call g(int), which according to overloading rules is the best choice, but g(X) via the implicit conversion int->X. The reason is that the point of instantiation for f<int> is just before h(). So with the instantiation made explicit, the example looks like this:
Code:
struct X { X(int); /* ... */ };
void g(X);
template <class T> void f(T a) { g(a); }
// This is the implicit instantiation of f<int>:
void f(int a) { g(a); }
void h()
{
extern void g(int);
f(2); // Invokes f(X(2)); that is, f<X>(X(2)) -- Note: this comment is incorrect!
}
Note that the implementation of f<int> doesn't see the declaration of g(int). All it sees is the declaration of g(X). Therefore, g(int) is never considered, and g(X) is called.
That's the entire issue.