Topic: 14.5.5.2 partial ordering of template functions


Author: Graeme Prentice <gp1@paradise.net.nz>
Date: Fri, 29 Mar 2002 16:07:05 GMT
Raw View

Partial ordering of template functions is used to resolve a call to an
overloaded template function.  I'm confused by section 14.5.5.2.
I know there is active issue 214 discussing deficiencies in 14.5.5.2.


<Section 14.5.5.2> says (amongst other things)

2 Given two overloaded function templates, whether one is more
specialized than another can be determined by transforming each
template in turn and using argument deduction (14.8.2) to compare it
to the other.=20

3 The transformation used is:
=97 For each type template parameter, synthesize a unique type and
substitute that for each occurrence of that parameter in the function
parameter list, or for a template conversion function, in the return
type.

....

4 Using the transformed function parameter list, perform argument
deduction against the other function tem-plate. The transformed
template is at least as specialized as the other if, and only if, the
deduction succeeds and the deduced parameter types are an exact match
(so the deduction does not rely on implicit conver-sions).

5 A template is more specialized than another if, and only if, it is
at least as specialized as the other template and that template is not
at least as specialized as the first.

</14.5.5.2>



My question is ...
In item 3 above, it says "synthesize a unique type"  - what exactly
does this mean.  From my Stroustrup book I learn that (roughly
speaking), for two functions f1(T) and f1(T*), the second is more
specialised because any call that matches the second, also matches the
first, but not vice versa.


Is the following what "synthesize a unique type" means?  ...


For two overloaded template functions f1-t, f1-u (where f1-t, f1-u are
the same name) and f1-t has template parameter types T1 thru Tm and
function parameter types t1 thru tn,  and f1-u has template parameter
types U1 thru Ur and function parameter types u1 thru us :-=20

1. If template argument deduction succeeds for a call to f1-u, with
parameters t1 thru tn, for all possible substitutions [note 1] of T1
thru Tm in the parameter list t1 thru tn, and the argument types in
the generated f1-u exactly match the calling types t1 thru tn, then
f1-t is at least as specialized as f1-u.

2. The reverse of 1.  If template argument deduction succeeds for a
call to f1-t, with parameters u1 thru us, for all possible
substitutions of U1 thru Ur in the parameter list u1 thru us, and the
argument types in the generated f1-t exactly match the calling types
u1 thru us, then f1-u is at least as specialized as f1-t.


Is that what the standard means?  If so, I can't see that there's any
"synthesizing" of types involved, nor do the types have to be unique,
nor is there any "transformation" involved  - or am I not
understanding?  The requirement for an "exact match" in the deduction,
means that differences in CV qualification (except on top level types)
cause a "failure/mismatch".


So for the following example

template <typename T, typename U>
void f1(T x, U y);         //A
       =20
template <typename U>
void f1(int, U y);         //B

//B is more specialised then //A because calling f1-A(int,U) produces
an exact match for any U, whereas calling f1-B(T,U) fails to match for
all T except T =3D=3D int.


Then what about the example in the standard 14.5.5.2

template<class T> void g(T);
template<class T> void g(T&);
float x;
g(x);   // ambiguous according to the standard

Active issue 214 item 2 suggests that g(T&) is more specialised than
g(T) so it should not be ambiguous  ... however, in section 14.8.2.1
"Deducing template arguments from a function call" the standard says
that  "If P is a reference type, the type referred to by P is used for
type deduction."

Does the statement in 14.8.2.1 mean that for void g(T&), when doing
the partial ordering, void g(T&) is treated as void g(T) when it's the
function being called?   - and hence the standard is correct in saying
that the call g(x) above is ambiguous, and that void g(T&) is not more
specialised than void g(T).  If so, issue 214 is correct in saying
that 14.5.5.2 is not clear about what "exact match" means  - similarly
with the CV qualification for void g(T const &)  - the const should be
ignored here when determining exact match  (since 14.8.2.1 says its
ignored for type deduction and g(T const &) can be called for any type
whether the calling type is const or not)



[note 1]  - "all possible substitutions"  -  does it have to be for
"all possible substitutions" and is this always easy to determine.


--
Graeme

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]