Topic: Defect Report: Partial ordering of function templates underspecified


Author: Martin von Loewis <loewis@informatik.hu-berlin.de>
Date: 2000/03/13
Raw View
[This text was jointly drafted with Martin Sebor of RogueWave]

In 14.5.5.2, [temp.func.order], partial ordering is explained in
terms of template argument deduction. However, the exact procedure for
doing so is not specified. A number of details is missing, they are
explained as sub-issues below. </p>

1. [temp.func.order]/2 refers to 14.8.2 [temp.deduct] for argument
deduction. This is the wrong reference; it explains how explicit
arguments are processed (14.8.2/2) and how function parameter types
are adjusted (14.8.2/3). Neither of these steps is meaningful in the
context of partial ordering. Next in deduction follows one of the
steps in 14.8.2.1 ([temp.deduct.call]), 14.8.2.2
([temp.deduct.funcaddr]), 14.8.2.3 ([temp.deduct.conv]), 14.8.2.4
([temp.deduct.type]). The standard does not specify which of these
contexts apply to partial ordering. =


2. Because 14.8.2.1 and 14.8.2.3 both start with actual function
parameters, it is meaningful to assume that partial ordering uses
14.8.2.4, which only requires types. With that assumption, the example
in 14.5.5.2/5 becames ill-formed, considering the two templates

template<class T> void g(T);  // #1
template<class T> void g(T&); // #2

Here, #2 is at least as specifialized as #1: With a synthetic type U,
#2 becomes g(U&); argument deduction against #1 succeeds with
T=3DU&. However, #1 is not at least as specialized as #2: Deducing
g(U) against g(T&) fails. Therefore, the second template is more
specialized than the first, and the call g(x) is not ambiguous.

3. According to John Spicer, the intent of the partial ordering was
that it uses deduction as in a function call (14.8.2.1), which is
indicated by the mentioning of "exact match" in 14.5.5.2/4. If that is
indeed the intent, it should be specified how values are obtained for
the step in 14.8.2.1/1, where the types of the arguments are
determined. Also, since 14.8.2.1/2 drops references from the parameter
type. Symmetrically, references should be dropped from the argument
type (which is done in 5, [expr]/2, for a true function call).

4. 14.5.5.2/4 requires an "exact match" for the "deduced parameter
types". It is not clear whether this refers to the template
parameters, or the parameters of the template function. Considering
the example

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

Here, #3 is clearly at least as specialized as #1. To determine
whether #1 is at least as specialized as #3, a unique type U is
synthesized, and deduction of g<U>(U) is performed against
#3. Following the rules in 14.8.2.1, deduction succeeds with T=3DU.
Since the template argument is U, and the deduced template parameter
is also U, we have an exact match between the template
parameters. Even though the conversion from U to U const & is an exact
match, it is not clear whether the added qualification should be taken
into account, as it is in other places.

Please let me know if you need more information.

Regards,
Martin v. L=F6wis



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Martin von Loewis <loewis@informatik.hu-berlin.de>
Date: 2000/03/14
Raw View
[Forwarded to standardization committee. -mha]

[This text was jointly drafted with Martin Sebor of RogueWave]

In 14.5.5.2, [temp.func.order], partial ordering is explained in
terms of template argument deduction. However, the exact procedure for
doing so is not specified. A number of details is missing, they are
explained as sub-issues below. </p>

1. [temp.func.order]/2 refers to 14.8.2 [temp.deduct] for argument
deduction. This is the wrong reference; it explains how explicit
arguments are processed (14.8.2/2) and how function parameter types
are adjusted (14.8.2/3). Neither of these steps is meaningful in the
context of partial ordering. Next in deduction follows one of the
steps in 14.8.2.1 ([temp.deduct.call]), 14.8.2.2
([temp.deduct.funcaddr]), 14.8.2.3 ([temp.deduct.conv]), 14.8.2.4
([temp.deduct.type]). The standard does not specify which of these
contexts apply to partial ordering.

2. Because 14.8.2.1 and 14.8.2.3 both start with actual function
parameters, it is meaningful to assume that partial ordering uses
14.8.2.4, which only requires types. With that assumption, the example
in 14.5.5.2/5 becames ill-formed, considering the two templates

template<class T> void g(T);  // #1
template<class T> void g(T&); // #2

Here, #2 is at least as specifialized as #1: With a synthetic type U,
#2 becomes g(U&); argument deduction against #1 succeeds with
T=U&. However, #1 is not at least as specialized as #2: Deducing
g(U) against g(T&) fails. Therefore, the second template is more
specialized than the first, and the call g(x) is not ambiguous.

3. According to John Spicer, the intent of the partial ordering was
that it uses deduction as in a function call (14.8.2.1), which is
indicated by the mentioning of "exact match" in 14.5.5.2/4. If that is
indeed the intent, it should be specified how values are obtained for
the step in 14.8.2.1/1, where the types of the arguments are
determined. Also, since 14.8.2.1/2 drops references from the parameter
type. Symmetrically, references should be dropped from the argument
type (which is done in 5, [expr]/2, for a true function call).

4. 14.5.5.2/4 requires an "exact match" for the "deduced parameter
types". It is not clear whether this refers to the template
parameters, or the parameters of the template function. Considering
the example

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

Here, #3 is clearly at least as specialized as #1. To determine
whether #1 is at least as specialized as #3, a unique type U is
synthesized, and deduction of g<U>(U) is performed against
#3. Following the rules in 14.8.2.1, deduction succeeds with T=U.
Since the template argument is U, and the deduced template parameter
is also U, we have an exact match between the template
parameters. Even though the conversion from U to U const & is an exact
match, it is not clear whether the added qualification should be taken
into account, as it is in other places.

Please let me know if you need more information.

Regards,
Martin v. L   wis
---
[ 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://reality.sgi.com/austern/std-c++/faq.html                  ]