Topic: Template clarification


Author: jamshid@ses.com (Jamshid Afshar)
Date: Sun, 23 Jan 1994 02:47:17 GMT
Raw View
Redirected to comp.std.c++.

In article <2hnbjb$ib0@zip.eecs.umich.edu>,
Michael Rice <mrice@quip.eecs.umich.edu> wrote:
>class base {};
>class derived : public base {};
>
>template <class T>
>int tfunc(base&, T) { return 1; }
>
>main() {
>  derived cout ;
>  tfunc(cout,1);
>  return 0;
>}
>Is this legal?  Should the compiler call int tfunc(base&, T) or give an
>error?                                                   ^^^-int

According to the ARM it should be an error.  It will likely be legal
ANSI/ISO C++ and some compilers already allow your code.  EDG and Cfront
allow it, g++ 2.5.5, BC++ and Watcom do not.  I encourage you to
complain to your vendor if they don't implement this extension.

>>From the ARM:
>Overloading resolution for template functions and other functions of the
>same name is done in three steps:
>  [1] Look for an exact match (13.2) on functions; if found, call it.
>  [2] Look for a function template from which a function that can be called
>      with an exact match can be generated; if found, call it.
>  [3] Try ordinary overloading resolution (13.2) for the functions; if a
>      function is found, call it.
>
>Obviously not found in [1].  Not an exact match in [2].

Note that even the exact match is meant literally (see "exactly matches"
in the next paragraph).  Not even trivial conversions are performed to
match a template function.  Fortunately most compilers aren't this
restrictive.  Lippman's 2nd Ed discusses the likely ANSI/ISO extensions
of allowing trivial conversions and even standard conversions on
parameters involving template arguments:

 template<class T>
 void foo( Base<T>& b );
 void bar( Derived<int> d ) {
     foo(d);  // probably will be legal -- generates foo(Base<int>&)
 }

I'm not sure if Lippman discusses your code, which involves a standard
conversion on a function argument which does not involve a template
argument.  At least BC++ for OS/2 made a distinction.  Confusingly, it's
README file said that it implemented the "Cfront" extension which allows
Derived<int> => Base<T> conversions, but BC++ specifically disallowed
your cout conversion above.  I don't know why Borland did this since
Cfront allows both.

>So the only way it could find it is in [3].
>Was [3] meant to include template functions or not?

No, a function template can be used to *generate* a function, but it is
not in itself a function.

Jamshid Afshar
jamshid@ses.com