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

2023-11-10

Issue 1244 was resolved by changing the example in 13.6 [temp.type] paragraph 1 from

template<template<class> class TT> struct X { }; template<class> struct Y { }; template<class T> using Z = Y<T>; X<Y> y; X<Z> z;

to

template<class T> struct X { }; template<class> struct Y { }; template<class T> using Z = Y<T>; X<Y<int> > y; X<Z<int> > z;

In fact, the original intent was that the example should have been
correct as written; however, the normative wording to make it so was
missing. The current wording of 13.7.8 [temp.alias] deals
only with the equivalence of a specialization of an alias template
with the *type-id* after substitution. Wording needs to be added
specifying under what circumstances an alias template itself is
equivalent to a class template.

**Proposed resolution (September, 2012):**

Add the following as a new paragraph following 13.7.8 [temp.alias] paragraph 2:

Change 13.6 [temp.type] paragraph 1 as follows:

...

their corresponding template

*template-argument*s refer to the same or equivalent (13.7.8 [temp.alias]) templates.

When the

type-idin the declaration of alias template (call itA) consists of asimple-template-idin which thetemplate-argument-listconsists of a list ofidentifiers naming eachtemplate-parameterofAexactly once in the same order in which they appear inA'stemplate-parameter-list, the alias template is equivalent to the template named in thesimple-template-id(call itT) ifAandThave the same number oftemplate-parameters. [Footnote:This rule is transitive: if an alias templateAis equivalent to another alias templateBthat is equivalent to a class templateC, thenAis also equivalent toC, andAandBare also equivalent to each other. —end footnote] [Example:template<typename T, U = T> struct A; template<typename V, typename W> using B = A<V, W>; // equivalent to A template<typename V, typename W> using C = A<V>; // not equivalent to A: // not all parameters used template<typename V> using D = A<V>; // not equivalent to A: // different number of parameters template<typename V, typename W> using E = A<W, V>; // not equivalent to A: // template-arguments in wrong order template<typename V, typename W = int> using F = A<V, W>; // equivalent to A: // default arguments not considered template<typename V, typename W> using G = A<V, W>; // equivalent to A and B template<typename V, typename W> using H = E<V, W>; // equivalent to E template<typename V, typename W> using I = A<V, typename W::type>; // not equivalent to A: // argument not identifier—

end example]

Two

template-ids refer to the same class or function if

[

Example:...declares

x2andx3to be of the same type. Their type differs from the types ofx1andx4.template<~~class T~~template<class> class TT> struct X { }; template<class> struct Y { }; template<class T> using Z = Y<T>; X<~~Y<int>~~Y> y; X<~~Z<int>~~Z> z;declares

yandzto be of the same type. —end example]

**Additional note, November, 2014:**

Concern has been expressed over the proposed resolution with regard to its handling of default template arguments that differ between the template and its alias, e.g.,

template<typename T, typename U = int> struct A {}; template<typename T, typename U = char> using B = A<T, U>; template<template<typename...> typename C> struct X { C<int> c; };

**Notes from the May, 2015 meeting:**

See also issue 1979, which CWG is suggesting to be resolved by defining a “simple” alias, one in which the SFINAE conditions are the same as the referenced template and that uses all template parameters.