logo
volkov / 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; // ошибка