*This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21
Core Issues List revision 115a.
See http://www.open-std.org/jtc1/sc22/wg21/ for the official
list.*

2024-07-24

#### 2160.
Issues with partial ordering

**Section: **13.7.7.3 [temp.func.order]
**Status: **open
**Submitter: **Richard Smith
**Date: **2015-07-16

(From this
editorial issue.)

**Consistency of deduced values**

template <typename T> void foo(T, T); // (1)
template <typename T, typename U> void foo(T, U); // (2)

13.10.3.6 [temp.deduct.type] paragraph 2 makes it clear
that there must be exactly one set of deduced values for the
`P`s. But there is no such statement in the partial ordering
rule. The algorithm described only does pairwise `P`/`A`
matching, so a synthesized call from (2) to (1) via `foo(U{},
V{})` could succeed in deduction. Both gcc and clang agree
that (1) is more specialized.

**Type Synthesis Template Instantiation**

template <typename T>
struct identity { using type = T; };
template<typename T> void bar(T, T ); // (1)
template<typename T> void bar(T, typename identity<T>::type ); // (2)

Here, if synthesized for (2) `Unique2` and `typename
identity<Unique2>::type == Unique2` , then type
deduction would succeed in both directions and the call
`bar(0,0)` would be ambiguous. However, it seems that
both compilers instead simply treat `typename
identity<Unique2>::type` as `Unique2_b`,
thus making template deduction from (2) to (1) fail (based
on the implied missing Consistency rule).

**Non-deduced Context Omission**

This is the same as the previous example, except now define

template <typename T> struct identity;
template <> struct identity<int> { using type = int; };

With no template instantiation during synthesis and
consistency, the (2) ==> (1) deduction fails. But if we
consider the (1) ==> (2) call, we'd match `T` against
`Unique1` and then have the non-deduced
context `typename identity<Unique1>::type` to
match against `Unique1`, but that would be a
substitution failure. It seems that the approach taken by
gcc and clang (both of which prefer (1) here) is to ignore
the non-deduced context argument, as long as that parameter
type is deduced from a different template parameter type
that did get matched.

**Notes from the February, 2016 meeting:**

None of these examples appears to reflect a defect in the
current wording; in particular, the second and third
examples involve a dependent type and there could be a later
specialization of `identity`, so it's impossible to
reason about those cases in the template definition
context. The issue will be left open to allow for possible
clarification of the intent of the wording.