R.7.1.3 Спецификация typedef
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; // ошибка