<HTML>
<HEAD>
   <style>
     <!--
       P.indented {margin-left: 4em}
       XMP.indented {margin-left: 4em}
     -->
   </style>
   <TITLE>
       Revisions to Partial Ordering Rules
   </TITLE>
</HEAD>

<BODY>

<TABLE ALIGN=RIGHT CELLSPACING=0 CELLPADDING=0 >
<TR>
<TD ALIGN=RIGHT>Document number:</TD>

<TD>&nbsp;02-0051/N1393</TD>
</TR>

<TR>
<TD ALIGN=RIGHT>Date:</TD>

<TD>&nbsp;September 9, 2002</TD>
</TR>

<TR>
<TD ALIGN=RIGHT>Author:</TD>
<TD>&nbsp;John Spicer, Edison Design Group</TD>
</TR>
<TR>
<TD></TD>

<TD>&nbsp;<TT>jhs@edg.com</TT></TD>
</TR>
<TR>
<TD ALIGN=RIGHT>Author:</TD>
<TD>&nbsp;John Wiegley, Borland</TD>
</TR>
<TR>
<TD></TD>

<TD>&nbsp;<TT>johnw@gnu.org</TT></TD>
</TR>

<TR>
<TD></TD>
</TR>
</TABLE>

<BR CLEAR=ALL>

<CENTER>
<H2>
Revisions to Partial Ordering Rules (issue 214)
</H2>
</center>

<h2>
Introduction
</h2>
<p>
The description of partial ordering as described in the standard suffers
from a number of problems:
<ol>
<li>
The specification is incomplete.  In particular, the way in which
partial ordering interfaces with the argument deduction rules is
unspecified.
<li>
The rules fail to account for templates in which some template
parameters are not used in the parameter and/or return types but
instead must be explicitly specified on the call.
<li>
<p>
The current (understood) rules do not correctly deal with comparison of
templates where one of the parameter types is a cv-qualified reference.
I say "understood" because it could be argued that the current rules are
not complete enough to know for sure <em>how</em> such cases are to be handled.
But the generally accepted understanding of the current rules does not
produce the desired results.
</ol>

<p>
With respect to #3 above, consider this case:
<XMP class=indented>
template <class T> struct A {};

template <class T> void f(const T&);  // #1
template <class T> void f(A<T>);      // #2

template <class T> void g(const T&);  // #3
template <class T> void g(T);         // #4

int main()
{
	A<int> ai;
	f(ai);    // should call #2
	g(ai);    // should call #3
}
</XMP>
<p>
The original proposal for partial ordering removed top-level references
and then top-level cv-qualifiers.  This had the property that the call of
<tt>f</tt> produced the desired result but the call of
<tt>g</tt> was ambiguous.  The current (understood) rules are
that top-level cv-qualifiers are removed before top-level references.  This
makes the call of <tt>g</tt> work but breaks <tt>f</tt>.  The rules proposed
by this paper provide a mechanism that makes both <tt>f</tt> and <tt>g</tt>
work without breaking any cases that worked previously.


<h2>
Standard Changes
</h2>

<p>
Change 14.5.5.2 paragraph 2 to read:

<blockquote>
Partial ordering selects which of two function templates is more
specialized than the other by transforming each template in turn
(see next paragraph) and performing template argument deduction
using the function parameter types, or in the case of a conversion
function the return type.  If the deduction succeeds, the transformed
function is said to be at least as specialized as the other.  If one
function is at least as specialized as the other, and the other is
not at least as specialized as the first, then the first is more
specialized.
</blockquote>

<p>
Change 14.5.5.2 paragraph 3 to read:

<blockquote>
<p>
To produce the transformed template, for each type, non-type, or template
template parameter synthesize a unique type, value, or class template
respectively and substitute that for each occurrence of that parameter
in the function type of the template.
</blockquote>

<p>
Change 14.5.5.2 paragraph 4 to read (note: the section reference
should refer to the section added to 14.8.2 below):
 
<blockquote>
<p>
Using the transformed function template's function parameter list,
or in the case of a conversion function its transformed return
type, perform type deduction against the function parameter list
(or return type) of the other function.  The transformed function
is at least as specialized as the other if, and only if, the
deduction succeeds and the deduced parameter types (or return type)
match the other function's parameter types (or return type) in such
a way that no implicit type conversions are required.  The mechanism
for performing these deductions is given in 14.8.2.x.
</blockquote>

<p>

Insert the following section before 14.8.2.4 (temp.deduct.type):
(Note that this would either be a new 14.8.2.4, or would be given
a number like 14.8.2.3a.  If neither of these is possible from
a troff point of view, this could be made 14.8.2.5)

<blockquote>

<h4> Deducing template arguments when determining the partial ordering
of function templates (temp.deduct.partial)
</h4>

<p>
Template argument deduction is done by comparing certain types associated with
the parameter template with the corresponding types from the argument
template.
<p>
Two sets of types are used to determine the partial ordering.  For each of
the templates involved there is the original function type and the
transformed function type (the creation of the transformed type is
described in 14.5.5.2).  The deduction process uses the
transformed type as the argument template and the original type of the
other template as the parameter template.  This process is done twice
for each type involved in the partial ordering comparison: once using
template-1 as the argument template and template-2 as the parameter
template and again using template-2 as the argument template and template-1
as the parameter template.
<p>
The types used to determine the ordering depend on the context in which
the partial ordering is done:

<ul>
<li>
In the context of a function call, the function template parameter types
are used.
<li>
In the context of a call to a conversion operator, the return types of
the conversion function templates are used.
<li>
In other contexts (temp.func.order), the function template's function type
is used.
</ul>

<p>
Each type from the parameter template and the corresponding type from the
argument template are used as the types of <tt>P</tt> and <tt>A</tt>.
<p>
Before the partial ordering is done, certain transformations are performed
on the types used for partial ordering:

<ul>
<li>
If <tt>P</tt> is a reference type, <tt>P</tt> is replaced by the type
referred to.
<li>
If <tt>A</tt> is a reference type, <tt>A</tt> is replaced by the type
referred to.
</ul>

<p>
If both <tt>P</tt> and <tt>A</tt> were reference types (before being replaced
with the type referred to above), determine which
of the two types (if any) is more cv-qualified than the other; otherwise
the types are considered to be equally cv-qualified for partial ordering
purposes.  The result of this determination will be used later.

<p>
Remove any top-level cv-qualifiers:
<ul>
<li>
If <tt>P</tt> is a cv-qualified type, <tt>P</tt> is replaced by the
cv-unqualified version of <tt>P</tt>.
<li>
If <tt>A</tt> is a cv-qualified type, <tt>A</tt> is replaced by the
cv-unqualified version of <tt>A</tt>.
</ul>

<p>
Using the resulting types <tt>P</tt> and <tt>A</tt> the deduction is then
done as described in (temp.deduct.type).

<p>
If, for a given type, deduction succeeds in both directions (i.e., the
types are identical after the transformations above) the more
cv-qualified type is considered to be more specialized.

<p>
In most cases, all template parameters must have values in order for
deduction to succeed, but for partial ordering purposes a template
parameter may remain without a value provided it is not used in the
types being used for partial ordering.  [Note: A template parameter used
in a non-deduced context is considered used.]

</blockquote>

<h3>End of document.</h3>

</body>











