86 lines
4.8 KiB
Markdown
86 lines
4.8 KiB
Markdown
[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*]
|