typedef
specifier
-
-
typedef- создает псевдоним, который может использоваться в любом месте вместо (возможно, сложного) имени типа.
-
Содержание |
Объяснение
Спецификатор typedef , когда используется в объявлении , указывает, что данное объявление является typedef-объявлением , а не объявлением переменной или функции.
Обычно спецификатор typedef появляется в начале объявления, хотя допускается его появление после спецификаторов типа , или между двумя спецификаторами типа. Спецификатор typedef не может быть объединен с любым другим спецификатором, кроме спецификаторов типа.
Объявление typedef может объявлять один или несколько идентификаторов на одной строке (например, int и указатель на int ), оно может объявлять типы массивов и функций, указатели и ссылки, классы и т.д. Каждый идентификатор, введённый в этом объявлении, становится typedef-именем , которое является синонимом для типа объекта или функции, которым он стал бы, если бы ключевое слово typedef было удалено.
Имена typedef являются псевдонимами для существующих типов и не являются объявлениями новых типов. typedef не может использоваться для изменения значения существующего имени типа (включая имя typedef). После объявления имя typedef может быть переобъявлено только для ссылки на тот же тип. Имена typedef действуют только в области видимости, где они видны: разные функции или объявления классов могут определять типы с одинаковыми именами, но разным значением.
Спецификатор typedef не может появляться в объявлении параметра функции, а также в decl-specifier-seq определения функции :
void f1(typedef int param); // некорректно typedef int f2() {} // некорректно
Спецификатор typedef не может использоваться в объявлении, не содержащем декларатор:
typedef struct X {}; // некорректный код
typedef-имя для целей компоновки
Если объявление typedef определяет безымянный класс или перечисление , то первое имя typedef для типа класса или типа перечисления, объявленное этим объявлением, является typedef-именем для целей линковки этого типа.
Например, в
typedef
struct
{
/* ... */
}
S
;
,
S
является typedef-именем для целей линковки. Класс или тип перечисления, определённый таким образом, имеет
внешнюю линковку
(если только он не находится в безымянном пространстве имён).
|
Класс без имени, определённый таким образом, должен содержать только C-совместимые конструкции. В частности, он не должен
и все классы-члены также должны удовлетворять этим требованиям (рекурсивно). |
(since C++20) |
Примечания
|
Псевдонимы типов предоставляют ту же функциональность, что и объявления typedef, используя другой синтаксис, а также применимы к именам шаблонов. |
(начиная с C++11) |
Ключевые слова
Пример
// простой typedef typedef unsigned long ulong; // следующие два объекта имеют одинаковый тип unsigned long l1; ulong l2; // более сложный typedef typedef int int_t, *intp_t, (&fp)(int, ulong), arr_t[10]; // следующие два объекта имеют одинаковый тип int a1[10]; arr_t a2; // внимание: следующие два объекта не имеют одинаковый тип const intp_t p1 = 0; // int *const p1 = 0 const int *p2; // распространенная идиома в C для избежания написания "struct S" typedef struct { int a; int b; } S, *pS; // следующие два объекта имеют одинаковый тип pS ps1; S* ps2; // ошибка: спецификатор класса памяти не может появляться в объявлении typedef // typedef static unsigned int uint; // typedef может использоваться в любом месте последовательности спецификаторов объявления long unsigned typedef int long ullong; // более традиционно пишется "typedef unsigned long long int ullong;" // std::add_const, как и многие другие метафункции, используют typedef-члены template<class T> struct add_const { typedef const T type; }; typedef struct Node { struct listNode* next; // объявляет новый (неполный) тип структуры с именем listNode } listNode; // ошибка: конфликтует с ранее объявленным именем структуры // C++20 ошибка: "структура с typedef-именем для связывания" имеет функции-члены typedef struct { void f() {} } C_Incompatible;
Отчеты о дефектах
Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены задним числом к ранее опубликованным стандартам C++.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| CWG 576 | C++98 | typedef не разрешался во всем определении функции | разрешен в теле функции |
| CWG 2071 | C++98 | typedef мог появляться в объявлении, не содержащем декларатор | теперь запрещено |
Смотрите также
|
Документация C
для
Объявление typedef
|