Ooops, sorry. I did not mean to have compile errors in there. I've fixed them above.
The second definition of g() doesn't hide the first since there is no inheritance involved. Rather, I've created
a partial specialization of Foo.
Since nobody else ventured an answer, you are again right -- B is output in all cases.
The moral to the story is that in the first set of programs, the
order of declaration, matters, and in the
second set, it does not. The reason?
Well, it's sorta complicated. First, you have to come to grips with the fact that in the first set of programs,
the second declaration of f is neither a specialization nor an overload candidate of the first. That said,
when the compiler sees the implementation of g() calling f() [which is at the point of g()'s implementation,
not at the point of g()'s instantiation in main], in the first program the compiler has not seen any f() declarations
yet, so it doesn't know what to call yet. But in the second program, it has already seen the first f(), and since that
absolutely matches the calling syntax of f() required by g(), it knows to call the first f() regardless of U and T. In
the third program, it has seen both f()'s by the time g() is parsed, so again, the compiler cannot know definitively
which one to call until g() is actually instantiated. Which means that if T is int, then the second f() will get called
since it is a better match according to the C++ matching rules.
Yes, the C++ standard was specifically written this way.
So... why does the second set of programs always output B, then? Because here, I have partially specialized Foo.
Note that in the first set of programs, f is NOT specialized according to the C++ standard. This specialization is
how we expect the compiler to behave, even in the first case. But it does not, and deliberately so.
Here is a nice link to a good explanation of this behavior:
http://www.gotw.ca/publications/mill17.htm
The reason I posted this was because I just fixed this bug -- my code was implemented using template functions
(progs 1-3) and the first f() was being called when I expected the second one to be called. It turns out that GCC 3.3
got this wrong, so my code was working because two wrongs indeed make a right in the case. When I upgraded
to GCC 4.x, my code stopped working, and it took quite a while to narrow this down, and to cement in my mind
that this was indeed my bug and not a compiler bug.
So
Grey Wolf, use template functions with care, unless the behavior of the compiler wrt template functions
makes perfect sense to you. I know that it didn't to me at first.
http://www.gotw.ca/publications/mill17.htm