This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

85
cppdraft/temp/alias.md Normal file
View File

@@ -0,0 +1,85 @@
[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.1Preamble[temp.pre]") in which the [*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]") is an[*alias-declaration*](dcl.pre#nt:alias-declaration "9.1Preamble[dcl.pre]") ([[dcl.pre]](dcl.pre "9.1Preamble")) declares the[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") to be an [*alias template*](#def:template,alias "13.7.8Alias 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.3Names 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.3Names of template specializations[temp.names]") that is not the operand of a [*reflect-expression*](expr.reflect#nt:reflect-expression "7.6.2.10The reflection operator[expr.reflect]") or
- [(2.2)](#2.2)
[*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6Splice 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.3Names of template specializations[temp.names]")*s* for the[*template-parameter*](temp.param#nt:template-parameter "13.2Template parameters[temp.param]")*s* in the [*defining-type-id*](dcl.name#nt:defining-type-id "9.3.2Type names[dcl.name]") of
the alias template[.](#2.sentence-1)
Any other [*template-id*](temp.names#nt:template-id "13.3Names of template specializations[temp.names]") that names a specialization of an alias template is
a [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4The 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.3Names of template specializations[temp.names]") is dependent, subsequent template
argument substitution still applies to the [*template-id*](temp.names#nt:template-id "13.3Names 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.2Type 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.1General[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.1General[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*]