13 Templates [temp]

13.6 Template declarations [temp.decls]

13.6.7 Alias templates [temp.alias]

An alias template is a name for a family of types.
The name of the alias template is a template-name.
When a template-id refers to the specialization of an alias template, it is equivalent to the associated type obtained by substitution of its template-arguments for the template-parameters in the type-id of the alias template.
Note
:
An alias template name is never deduced.
— end note
 ]
Example
:
template<class T> struct Alloc { /* ... */ };
template<class T> using Vec = vector<T, Alloc<T>>;
Vec<int> v;         // same as vector<int, Alloc<int>> v;

template<class T>
  void process(Vec<T>& v)
  { /* ... */ }

template<class T>
  void process(vector<T, Alloc<T>>& w)
  { /* ... */ }     // error: redefinition

template<template<class> class TT>
  void f(TT<int>);

f(v);               // error: Vec not deduced

template<template<class,class> class TT>
  void g(TT<int, Alloc<int>>);
g(v);               // OK: TT = vector
— end example
 ]
However, if the template-id is dependent, subsequent template argument substitution still applies to the template-id.
Example
:
template<typename...> using void_t = void;
template<typename T> void_t<typename T::foo> f();
f<int>();           // error, int does not have a nested type foo
— end example
 ]
The type-id in an alias template declaration shall not refer to the alias template being declared.
The type produced by an alias template specialization shall not directly or indirectly make use of that specialization.
Example
:
template <class T> struct A;
template <class T> using B = typename A<T>::U;
template <class T> struct A {
  typedef B<T> U;
};
B<short> b;         // error: instantiation of B<short> uses own type via A<short>​::​U
— end example
 ]
The type of a lambda-expression appearing in an alias template declaration is different between instantiations of that template, even when the lambda-expression is not dependent.
Example
:
template <class T>
  using A = decltype([] { });   // A<int> and A<char> refer to different closure types
— end example
 ]