Proposed resolution for 2019 comment CA 112

Document number: P2113R0
Date: 2020-02-13
Project: ISO/IEC JTC 1/SC 22/WG 21/C++
Audience subgroup: Core
Revises: None
Reply-to: Hubert S.K. Tong <>


Consistent with the direction from Belfast (and the proposed change submitted with CA 112), the property of “structural” partial ordering that it ignores the form of function parameters for which arguments are not provided on the call expression is not replicated in the consideration of constraints. The form of such function parameters are not ignored for the case of non-template (but templated) functions. There is also no precedent for handling the constraints that relate to such function parameters (e.g., if there are constraints that involve template parameters for either template that are without a deduced argument after the two-way deduction process) in a way that they are ignored.

This also resolves (with modification) comment US 120.

Proposed Wording

In relation to N4849, modify in subclause [] paragraph 6:

Two template-heads are equivalent if their template-parameter-lists have the same length, corresponding template-parameters are equivalent and such that if either template-parameter is declared with a type-constraint, they are both declared with type-constraints that are equivalent, and if either template-head has a requires-clause, they both have requires-clauses and the corresponding constraint-expressions are equivalent. Two template-parameters are equivalent under the following conditions:

[ … ]

In relation to N4849, modify in subclause [temp.func.order] paragraph 2:

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 type. The deduction process determines whether one of the templates is more specialized than the other. If so, the more specialized template is the one chosen by the partial ordering process. If both deductions succeed, the partial ordering selects the more constrained template (if one exists) as described by the rules in [temp.constr.order] determined below.

Add a new paragraph to subclause [temp.func.order] after paragraph 4:

Using the transformed function template’s function type, perform type deduction against the other template as described in [temp.deduct.partial].

[Example: …]

If deduction against the other template succeeds for both transformed templates, constraints can be considered as follows:


template <typename> constexpr bool True = true;
template <typename T> concept C = True<T>;

void f(C auto &, auto &) = delete;
template <C Q> void f(Q &, C auto &);

void g(struct A *ap, struct B *bp) {
  f(*ap, *bp);  // OK: Can use different methods to produce template parameters

template <typename T, typename U> struct X {};

template <typename T, C U, typename V>
bool operator==(X<T, U>, V) = delete;
template <C T, C U, C V>
bool operator==(T, X<U, V>);

void h() {
  X<void *, int>{} == 0; // OK: Correspondence of [T, U, V] and [U, V, T]

end example]