[dcl.typedef]

# 9 Declarations [[dcl]](./#dcl)

## 9.2 Specifiers [[dcl.spec]](dcl.spec#dcl.typedef)

### 9.2.4 The typedef specifier [dcl.typedef]

[1](#1)

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

Declarations containing the [*decl-specifier*](dcl.spec.general#nt:decl-specifier "9.2.1 General [dcl.spec.general]") typedef declare [*type aliases*](#def:alias,type "9.2.4 The typedef specifier [dcl.typedef]")[.](#1.sentence-1)

The typedef specifier shall not be
combined in a [*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1 General [dcl.spec.general]") with any other kind of
specifier except a [*defining-type-specifier*](dcl.type.general#nt:defining-type-specifier "9.2.9.1 General [dcl.type.general]"), and it shall not be used in the[*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1 General [dcl.spec.general]") of a[*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")) nor in the[*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1 General [dcl.spec.general]") of a[*function-definition*](dcl.fct.def.general#nt:function-definition "9.6.1 General [dcl.fct.def.general]") ([[dcl.fct.def]](dcl.fct.def "9.6 Function definitions"))[.](#1.sentence-2)

If a typedef specifier appears in a declaration without a [*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]"),
the program is ill-formed[.](#1.sentence-3)

[typedef-name:](#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]")  
[*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")  
[*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]")

A name declared with the typedef specifier becomes a[*typedef-name*](#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]")[.](#1.sentence-4)

The underlying entity of the type alias is
the type associated with the [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") ([[dcl.decl]](dcl.decl "9.3 Declarators"))
or [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") ([[temp.pre]](temp.pre "13.1 Preamble"))[.](#1.sentence-5)

A [*typedef-name*](#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") does not introduce a new type the way a class
declaration ([[class.name]](class.name "11.3 Class names")) or enum declaration ([[dcl.enum]](dcl.enum "9.8.1 Enumeration declarations")) does[.](#1.sentence-6)

[*Example [1](#example-1)*:

Aftertypedef int MILES, *KLICKSP; the constructionsMILES distance;extern KLICKSP metricp; are all correct declarations; the type of distance isint and that of metricp is âpointer to intâ[.](#1.sentence-7)

â *end example*]

[2](#2)

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

A type alias can also be declared by an[*alias-declaration*](dcl.pre#nt:alias-declaration "9.1 Preamble [dcl.pre]")[.](#2.sentence-1)

The [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") following theusing keyword is not looked up;
it becomes the [*typedef-name*](#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") of a type alias
and the optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") following the[*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") appertains to that type alias[.](#2.sentence-2)

Such a type alias has the same
semantics as if it were introduced by the typedef specifier[.](#2.sentence-3)

[*Example [2](#example-2)*: using handler_t = void (*)(int);extern handler_t ignore;extern void (*ignore)(int); // redeclare ignoretemplate<class T> struct P { };using cell = P<cell*>; // error: cell not found ([[basic.scope.pdecl]](basic.scope.pdecl "6.4.2 Point of declaration")) â *end example*]

The [*defining-type-specifier-seq*](dcl.type.general#nt:defining-type-specifier-seq "9.2.9.1 General [dcl.type.general]") of the [*defining-type-id*](dcl.name#nt:defining-type-id "9.3.2 Type names [dcl.name]") shall not define
a class or enumeration if the [*alias-declaration*](dcl.pre#nt:alias-declaration "9.1 Preamble [dcl.pre]") is the [*declaration*](dcl.pre#nt:declaration "9.1 Preamble [dcl.pre]") of a [*template-declaration*](temp.pre#nt:template-declaration "13.1 Preamble [temp.pre]")[.](#2.sentence-4)

[3](#3)

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

A [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") is only a [*typedef-name*](#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") if its [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") names
an alias template or a type template template parameter[.](#3.sentence-1)

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

A [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") that names a class template specialization
is a [*class-name*](class.pre#nt:class-name "11.1 Preamble [class.pre]") ([[class.name]](class.name "11.3 Class names"))[.](#3.sentence-2)

If a [*typedef-name*](#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") is used to identify the subject of an[*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]") ([[dcl.type.elab]](dcl.type.elab "9.2.9.5 Elaborated type specifiers")), a [class
definition](class "11 Classes [class]"), a [constructor
declaration](class.ctor "11.4.5 Constructors [class.ctor]"), or a [destructor
declaration](class.dtor "11.4.7 Destructors [class.dtor]"), the program is ill-formed[.](#3.sentence-3)

â *end note*]

[*Example [3](#example-3)*: struct S { S(); ~S();};

typedef struct S T;

S a = T(); // OKstruct T * p; // error â *end example*]

[4](#4)

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

An unnamed class or enumeration C defined in a typedef declaration has
the first [*typedef-name*](#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") declared by the declaration to be of type C as its [*typedef name for linkage purposes*](#def:typedef_name_for_linkage_purposes "9.2.4 The typedef specifier [dcl.typedef]") ([[basic.link]](basic.link "6.7 Program and linkage"))[.](#4.sentence-1)

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

A typedef declaration involving a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") does not itself define the associated closure type,
and so the closure type is not given a typedef name for linkage purposes[.](#4.sentence-2)

â *end note*]

[*Example [4](#example-4)*: typedef struct { } *ps, S; // S is the typedef name for linkage purposestypedef decltype([]{}) C; // the closure type has no typedef name for linkage purposes â *end example*]

[5](#5)

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

An unnamed class with a typedef name for linkage purposes shall not

- [(5.1)](#5.1)

declare any members
 other than non-static data members, member enumerations, or member classes,

- [(5.2)](#5.2)

have any base classes or default member initializers, or

- [(5.3)](#5.3)

contain a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]"),

and all member classes shall also satisfy these requirements (recursively)[.](#5.sentence-1)

[*Example [5](#example-5)*: typedef struct {int f() {}} X; // error: struct with typedef name for linkage has member functions â *end example*]
