Topic: template fn arg matching


Author: Marcelo Cantos <marcelo@mds.rmit.edu.au>
Date: 1997/01/17
Raw View
John Lilley wrote:
>
> Michael C. Greenspon wrote:
> >
> > template<class T>
> > S& operator<< ( S&, T ) { ... };    // valid for template args T of class type
> >
> > template<class T>
> > S& operator<< ( S&, T* ) { ... };   // valid for template args T of ptr type
> >
> > f() {
> >    S s;
> >    X x;
> >    X* xp = &x;
> >
> >    s << x;     // invoke first version of template fn for T
> >    s << xp;    // invoke second version for T*
> >
> > }
> >
> > Currently if I declare something like the above, the compiler (IBM xlC)
> > reports, legitimately I suppose, that the second invokation s << xp
> > matches more than one template function, operator << ( S&, X* ) and
> > operator << ( S&, X** ).

Both templates fit 's << xp;' with equal closeness. Because the first
template has a completely generic parameter it is a perfect fit for
any type you throw at it.


--
__________________________________________________
Multimedia Database Systems Group, RMIT, Australia
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: John Lilley <jlilley@empathy.com>
Date: 1997/01/18
Raw View
Marcelo Cantos wrote:

> Michael C. Greenspon wrote:
> > template<class T> S& operator<< ( S&, T );
> > template<class T> S& operator<< ( S&, T* );
...
> >    s << x;     // invoke first version of template fn for T
> >    s << xp;    // invoke second version for T*


> Both templates fit 's << xp;' with equal closeness. Because the first
> template has a completely generic parameter it is a perfect fit for
> any type you throw at it.


Not any more...  The dec96 draft 14.5.5.2 [temp.func.order] sets forth a
partial ordering of function templates.  In the above example, the
second operator<<() is more specialized, and will be chosen for pointers
over the first operator<<().

john lilley


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: mcg@sequin.com (Michael C. Greenspon)
Date: 1997/01/03
Raw View
How can one declare a pair of template functions, one of which matches
overloaded args of class type T and the other of which matches only
instantiations of type T*? Is there a notion of specialization that covers
this situation, and is it one that can be compiled with current compilers?

Specifically I want to do something like:

class S;
class X;

template<class T>
S& operator<< ( S&, T ) { ... };    // valid for template args T of class type

template<class T>
S& operator<< ( S&, T* ) { ... };   // valid for template args T of ptr type


f() {
   S s;
   X x;
   X* xp = &x;

   s << x;     // invoke first version of template fn for T
   s << xp;    // invoke second version for T*

}

Currently if I declare something like the above, the compiler (IBM xlC)
reports, legitimately I suppose, that the second invokation s << xp
matches more than one template function, operator << ( S&, X* ) and
operator << ( S&, X** ).

In fact I also want a third template fn, to distinguish implementations
for class type T, ptr to class type T* and array of ptr to class type,
i.e. T**.

What is the appropriate way to declare this? I actually want to do this
with operator fns like the example above, so I think I can't use
additional args or tags. Perhaps a wrapper but I'd like to avoid that if
possible.

Email responses appreciated.

Thanks,
--Michael
mcg@grok.berkeley.edu


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: jlilley@empathy.com (John Lilley)
Date: 1997/01/05
Raw View
Michael C. Greenspon wrote:
>
> template<class T>
> S& operator<< ( S&, T ) { ... };    // valid for template args T of class type
>
> template<class T>
> S& operator<< ( S&, T* ) { ... };   // valid for template args T of ptr type
>
> f() {
>    S s;
>    X x;
>    X* xp = &x;
>
>    s << x;     // invoke first version of template fn for T
>    s << xp;    // invoke second version for T*
>
> }
>
> Currently if I declare something like the above, the compiler (IBM xlC)
> reports, legitimately I suppose, that the second invokation s << xp
> matches more than one template function, operator << ( S&, X* ) and
> operator << ( S&, X** ).

Someone correct me if I'm wrong here -- I think that this should work.
The draft standard allows for overloading of template function like
this, and provides for resolution based on the "closest fit".  However,
few compilers have actually caught up to the state of the draft
standard, in no small part because it has been moving so fast.

john lilley


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: fwai@armltd.co.uk (Francis Wai)
Date: 1997/01/06
Raw View
mcg@sequin.com (Michael C. Greenspon) writes:

>Specifically I want to do something like:

>class S;
>class X;

>template<class T>
>S& operator<< ( S&, T ) { ... };    // valid for template args T of class type

>template<class T>
>S& operator<< ( S&, T* ) { ... };   // valid for template args T of ptr type


>f() {
>   S s;
>   X x;
>   X* xp = &x;

>   s << x;     // invoke first version of template fn for T
>   s << xp;    // invoke second version for T*

>}

>Currently if I declare something like the above, the compiler (IBM xlC)
>reports, legitimately I suppose, that the second invokation s << xp
>matches more than one template function, operator << ( S&, X* ) and
>operator << ( S&, X** ).

The IBM compiler is wrong. BUT, it is not clear how conformant it is to
the latest proposed Draft. The second template function (operator) is
considered more specialised than the first and a partial ordering exists
and applies in the second call. This partial ordering does not apply in
the first call since type deduction fails for the second template function.

--Francis


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: David Vandevoorde <daveed@vandevoorde.com>
Date: 1997/01/07
Raw View
Michael C. Greenspon wrote:
[...]
> Specifically I want to do something like:
>
> class S;
> class X;
>
> template<class T>
> S& operator<< ( S&, T ) { ... };    // valid for template args T of > class type
>
> template<class T>
> S& operator<< ( S&, T* ) { ... };   // valid for template args T of > ptr type
[...]

It is legitimate a legitimate concept called ``partial function template
specialization''. Recent HP compilers support this fairly new C++
language feature.

 Daveed
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: jlilley@empathy.com (John Lilley)
Date: 1997/01/07
Raw View
Michael C. Greenspon wrote:
>
> How can one declare a pair of template functions...
> class S;
> class X;
> template<class T> S& operator<< ( S&, T ) { ... };
> template<class T> S& operator<< ( S&, T* ) { ... };
>
> f() {
>    X* xp = &x;
>    s << xp;    // error -- ambiguous
> }
>
> ...matches more than one template function...

I must reconsider my previous post.  After reading the may96 DWP more
closely, your example is clearly (at least to me) ambiguous:

"... template argument deduction is performed for each function template
to find the template argument values (if any) that can be used with that
function template to instantiate a function template specialization that
can be invoked with the call arguments.  For each function template, if
the argument deduction succeeds, the deduced template-arguments are used
to instantiate a single function template specialization that is added
to the candidate set of functions to be used in overload resolution..."

In other words, your overloaded template operator functions will both
produce a valid specialization taking the arguments (S&, X*).  Since
these take the same arguments, then they are ambiguous.  Actually, I
don't think that "ambiguous" is quite the right word for this -- it's
more like a duplicate definition.

I could not find any language (in the may96 DWP) that supports an
ordering of template function specializations.  In a later message,
David Vandevoorde (daveed@vandevoorde.com) claims that there is a new
C++ language feature supporting template function partial specialization
that would (he implies) order the template functions according to a best
fit on the deduced arguments.  Have I missed somthing?  Does this appear
in a later draft?  I'd really like to know correct interpretation
according to the latest draft.

If there is a template function specialization, does it support the
analogous syntax to template class explicit specializations e.g.:

template <> void foo<int> (...) { ... }

Please send email if possible.

john lilley
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: mcg@wheezy.CS.Berkeley.EDU (Michael C. Greenspon)
Date: 1997/01/08
Raw View
In article <5aqrdm$sk3@sis.armltd.co.uk>, fwai@armltd.co.uk (Francis Wai) wrote:


> The IBM compiler is wrong. BUT, it is not clear how conformant it is to
> the latest proposed Draft. The second template function (operator) is
> considered more specialised than the first and a partial ordering exists
> and applies in the second call. This partial ordering does not apply in
> the first call since type deduction fails for the second template function.
>
> --Francis

Well that's heartening. (In IBM's defense the version of xlC we're using
supports ARM and most post ARM features rather well, but not DWP features
yet.)  Unfortunately the new language features don't help our codebase
since few of the new features are supported consistently across current
compilers.

In the mean time, I've used explicit wrappers--

template <class T>
struct ptr_to {  T* t;
         ptr_to(T* t_) : t(t_) {};
         T& operator*() { return *t; }
         T& operator[](int i) { return t[i]; }
         T* operator->() { return t; }
   // etc. other pointer-like operators...
};

so I can write the generic templates and specializations as

template<class T>
S& operator<< ( S&, T ) { ... };    // valid for template args T of class type


template<class T>
S& operator<< ( S&, ptr_to<T> ) { ... };
                           // valid for template args T of ptr to class type

In the future (year 2000) when most compilers support the new features, we
can change ptr_to<T> back to T* etc.

--Michael


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]