[temp.alias]

# 13 Templates [[temp]](./#temp)

## 13.7 Template declarations [[temp.decls]](temp.decls#temp.alias)

### 13.7.8 Alias templates [temp.alias]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4592)

A [*template-declaration*](temp.pre#nt:template-declaration "13.1 Preamble [temp.pre]") in which the [*declaration*](dcl.pre#nt:declaration "9.1 Preamble [dcl.pre]") is an[*alias-declaration*](dcl.pre#nt:alias-declaration "9.1 Preamble [dcl.pre]") ([[dcl.pre]](dcl.pre "9.1 Preamble")) declares the[*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") to be an [*alias template*](#def:template,alias "13.7.8 Alias templates [temp.alias]")[.](#1.sentence-1)

An alias template is a name for a family of
types[.](#1.sentence-2)

The name of the alias template is a [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]")[.](#1.sentence-3)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4599)

A

- [(2.1)](#2.1)

[*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") that is not the operand of a [*reflect-expression*](expr.reflect#nt:reflect-expression "7.6.2.10 The reflection operator [expr.reflect]") or

- [(2.2)](#2.2)

[*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]")

that designates the specialization of
an alias template is equivalent to the associated type obtained by
substitution of its [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s* for the[*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]")*s* in the [*defining-type-id*](dcl.name#nt:defining-type-id "9.3.2 Type names [dcl.name]") of
the alias template[.](#2.sentence-1)

Any other [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") that names a specialization of an alias template is
a [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") for a type alias[.](#2.sentence-2)

[*Note [1](#note-1)*:

An alias template name is never deduced[.](#2.sentence-3)

â *end note*]

[*Example [1](#example-1)*: 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: redefinitiontemplate<template<class> class TT>void f(TT<int>);

f(v); // error: Vec not deducedtemplate<template<class,class> class TT>void g(TT<int, Alloc<int>>);
g(v); // OK, TT = vector â *end example*]

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4644)

However, if the [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") is dependent, subsequent template
argument substitution still applies to the [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]")[.](#3.sentence-1)

[*Example [2](#example-2)*: 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*]

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4655)

The [*defining-type-id*](dcl.name#nt:defining-type-id "9.3.2 Type names [dcl.name]") in an alias template declaration shall not refer to
the alias template being declared[.](#4.sentence-1)

The type produced by an alias template
specialization shall not directly or indirectly make use of that specialization[.](#4.sentence-2)

[*Example [3](#example-3)*: 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*]

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4670)

The type of a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") appearing in an alias template declaration
is different between instantiations of that template,
even when the [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") is not dependent[.](#5.sentence-1)

[*Example [4](#example-4)*: template <class T>using A = decltype([] { }); // A<int> and A<char> refer to different closure types â *end example*]
