Files
2025-10-25 03:02:53 +03:00

86 lines
4.8 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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*]