Справочное руководство по C++

R.7.1.3 Спецификация typedef.

Описания со спецификацией typedef задают идентификаторы, которые позднее могут использоваться для обозначения основных или производных типов. Спецификация typedef недопустима в определении-функции (§R.8.3).

Имя-typedef:

 идентификатор.

В пределах области видимости (§R.3.2) описания typedef любой идентификатор, появляющийся в части любого из описателей, становится синтаксически эквивалентным служебному слову и обозначает тип, связанный с данным идентификатором, как описано в §R.8. Таким образом, имя-typedef является синонимом другого типа. В отличие от описания класса (§R.9.1) имя-typedef не добавляет нового типа. Например, после описания.

Typedef int MILES, *KLICKSP;

Конструкции.

MILES distance;

Extern KLICKSP metricp;

Являются законными описаниями, тип distance есть int, а у metricp тип "указатель на int".

С помощью typedef можно переопределить имя так, чтобы оно опять обозначало тип, на который уже ссылалось, причем даже в той области видимости, в которой тип был первоначально описан, например,

Typedef struct s {/*… */} s;

Typedef int I;

Typedef int I;

Typedef I I;

Безымянный класс, который определяется в typedef, получает в качестве своего имени имя, использованное в typedef, например,

Typedef struct {/*… */} S; // имя структуры стало S.

С помощью описания typedef нельзя переопределить имя типа, описанного в этой же области видимости, так, чтобы оно обозначало другой тип, например,

Class complex {/*… */};

Typedef int complex; // ошибка: переопределение.

Аналогично, нельзя описывать класс с именем типа, описанного в этой же области видимости, так, чтобы он обозначал другой тип, например,

Typedef int complex;

Class complex {/*… */}; // ошибка: переопределение.

Имя-typedef, которое обозначает класс, является именем-класса (§R.9.1). Синоним нельзя использовать после следующих префиксов: class, struct и union, а также в именах конструкторов и деструкторов в описании самого класса, например,

Struct S {

 S();

 ~S();

};

Typedef struct S T;

S a = T(); // нормально.

Struct T* p; // ошибка.