CWG Issue 1395 (original) (raw)

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

2025-11-05


1395. Partial ordering of variadic templates reconsidered

Section: 13.10.3.6 [temp.deduct.type]Status: C++17Submitter: John SpicerDate: 2011-09-21

[Moved to DR at the November, 2016 meeting.]

The resolution of issue 692 (found in document N3281) made the following example ambiguous and thus ill-formed:

template<class T>
void print(ostream &os, const T &t) {
    os << t;
}

template <class T, class... Args>
void print(ostream &os, const T &t, const Args&... rest) {
    os << t << ", ";
    print(os, rest...);
}

int main() {
    print(cout, 42);
    print(cout, 42, 1.23);
}

This pattern seems fairly intuitive; is it reason to reconsider or modify the outcome of issue 692?

(See also issue 1432.)

Notes from the October, 2012 meeting:

CWG agreed that the example should be accepted, handling this case as a late tiebreaker, preferring an omitted parameter over a parameter pack.

Additional note (March, 2013):

For another example:

template<typename ...T> int f(T*...) { return 1; } template int f(const T&) { return 2; } int main() { if (f((int*)0) != 1) { return 1; } return 0; }

This worked as expected prior to the resolution ofissue 692.

Proposed resolution (June, 2016):

  1. Change 13.10.3.5 [temp.deduct.partial] paragraph 8 as follows:

If A was transformed from a function parameter pack and P is not a parameter pack, type deduction fails. Otherwise, using Using the resulting types P and A, the deduction is then done as described in 13.10.3.6 [temp.deduct.type]. If P is a function parameter pack, the type A of each remaining parameter type of the argument template is compared with the type P of the _declarator-id_of the function parameter pack. Each comparison deduces template arguments for subsequent positions in the template parameter packs expanded by the function parameter pack. Similarly, if A was transformed from a function parameter pack, it is compared with each remaining parameter type of the parameter template. If deduction succeeds for a given type, the type from the argument template is considered to be at least as specialized as the type from the parameter template. [Example:...

  1. Add the following as a new paragraph following 13.10.3.5 [temp.deduct.partial] paragraph 10:

Function template F is at least as specialized as function template G if, for each pair of types used to determine the ordering, the type from F is at least as specialized as the type from G. F is more specialized than Gif F is at least as specialized as G and G is not at least as specialized as F.

If, after considering the above, function template F is at least as specialized as function template G and vice-versa, and ifG has a trailing paramter pack for which F does not have a corresponding parameter, and if F does not have a trailing parameter pack, then F is more specialized than G.

This resolution also resolves issue 1825.