Re: Overloading template functions
"Zeppe" <zeppe@.remove.all.this.long.comment.email.it> wrote in message
news:f2f6hh$uui$1@aioe.org...
Sylvester Hesp wrote:
tail.tail is of type ::cons_end, thus the global namespace is searched
for the name 'foo4' at point of instantiation (in main()). In main(),
foo4(cons<T,cons_end>) is known, and because it is more specialized, that
function is called.
testspecialization.cpp: In function ?void foo4(U, V) [with U = int, V =
cons_end]?:
testspecialization.cpp:14: instantiated from ?void foo4(U, V) [with U =
int, V = cons<int, cons_end>]?
testspecialization.cpp:26: instantiated from here
testspecialization.cpp:14: error: ?struct cons_end? has no member named
?elem?
testspecialization.cpp:14: error: ?struct cons_end? has no member named
?tail?
for g++ the istantiation of the second call to foo4 is inside foo4<U,V>.
-----------
14.6.4.1/1 For a function template specialization, a member function
template specialization, or a specialization for a member function or static
data member of a class template, if the specialization is implicitly
instantiated because it is referenced from within another template
specialization and the context from which it is referenced
depends on a template parameter, the point of instantiation of the
specialization is the point of instantiation of the enclosing
specialization. Otherwise, the point of instantiation for such a
specialization immediately follows the namespace scope declaration or
definition that refers to the specialization.
-----------
So, the point of instantiation is in main()
I don't know if it is standard, but I suppose it is. A simple function
declaration works just well, and it is also quite reasonable, given that
you don't usually call a function without having declared it...
Actually, it happens all the time:
#include <set>
class MyType
{
// whatever
};
bool operator <(MyType&, MyType&);
int main()
{
std::set<MyType> s;
s.insert(MyType);
}
std::set<T> uses std::less<T> to compare types. The (least specialized
version of) std::less<T> uses the < operator for comparison. But,
operator<(MyType&, MyType&) is declared *after* the implementation of
std::less<T> (which is defined by including <set> at the top of the
sourcefile).
Not having this kind of two-phase name lookup (14.6.4) is devestating for
the use of templates and generic programming. Luckily, compilers that do not
fully implement the two-phase name lookup (VC++ for example) do implement
the second part (lookup at point of instantiation), which is imho the most
important one.
- Sylvester