- Title
- Issues with partial ordering
- Status
- open
- Section
- 17.6.6.2 [temp.func.order]
- Submitter
- Richard Smith

Created on **2015-07-16.00:00:00**,
last changed **2017-02-06.00:00:00**.

Date: 2016-02-15.00:00:00

**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.

Date: 2017-02-06.00:00:00

(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)

17.9.2.5 [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.

History | |||
---|---|---|---|

Date | User | Action | Args |

2017-02-06 00:00:00 | admin | set | messages: + msg5828 |

2015-07-16 00:00:00 | admin | create |