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

2023-12-02


744. Matching template arguments with template template parameters with parameter packs

Section: 13.4.4  [temp.arg.template]     Status: CD2     Submitter: Faisal Vali     Date: 2 November, 2008

[Voted into WP at March, 2010 meeting.]

According to 13.4.4 [temp.arg.template] paragraph 3,

A template-argument matches a template template-parameter (call it P) when each of the template parameters in the template-parameter-list of the template-argument's corresponding class template or template alias (call it A) matches the corresponding template parameter in the template-parameter-list of P. When P's template-parameter-list contains a template parameter pack (13.7.4 [temp.variadic]), the template parameter pack will match zero or more template parameters or template parameter packs in the template-parameter-list of A with the same type and form as the template parameter pack in P (ignoring whether those template parameters are template parameter packs).

The immediately-preceding example, however, assumes that a parameter pack in the parameter will match only a parameter pack in the argument:

    template<class T> class A { /* ... */ };
    template<class T, class U = T> class B { /* ... */ };
    template<class ... Types> class C { /* ... */ };

    template<template<class ...> class Q> class Y { /* ... */ };

    Y<A> ya;  // ill-formed: a template parameter pack does not match a template parameter
    Y<B> yb;  // ill-formed: a template parameter pack does not match a template parameter
    Y<C> yc;  // OK

Proposed resolution (February, 2010):

Change the final three lines of the second example in 13.4.4 [temp.arg.template] paragraph 2 as follows:

    Y<A> ya;  // ill-formed: a template parameter pack does not match a template parameter OK
    Y<B> yb;  // ill-formed: a template parameter pack does not match a template parameter OK
    Y<C> yc;  // OK