typedef спецификатор
-
typedef— создаёт псевдоним, который можно использовать вместо имени типа (возможно, сложного).
Пояснение
Спецификатор typedef, используемый в объявлении, указывает, что это объявление typedef, а не объявление переменной или функции.
Обычно спецификатор typedef располагается в начале объявления, хотя его разрешено помещать после спецификаторов типа или между двумя спецификаторами типа. Спецификатор typedef нельзя объединять ни с какими другими спецификаторами, кроме спецификаторов типа.
Объявление typedef может объявлять один или несколько идентификаторов в одной строке (например, int и указатель на int); оно может объявлять типы массивов и функций, указатели и ссылки, типы классов и т. д. Каждый идентификатор, введённый в этом объявлении, становится именем typedef, которое является синонимом типа объекта или функции, которыми он стал бы, если бы ключевое слово typedef было удалено.
Имена typedef являются псевдонимами существующих типов и не объявляют новые типы. typedef нельзя использовать для изменения значения существующего имени типа (включая имя typedef). После объявления имя typedef можно объявить повторно только для ссылки на тот же тип. Имена typedef действуют только в области видимости, где они видны: в разных функциях или объявлениях классов могут определяться одноимённые типы с разными значениями.
Спецификатор typedef не может присутствовать в объявлении параметра функции или в decl-specifier-seq определения функции:
void f1(typedef int param); // ill-formed
typedef int f2() {} // ill-formed
Спецификатор typedef не может присутствовать в объявлении, не содержащем декларатора:
typedef struct X {}; // ill-formed
Имя typedef для целей связывания
Если объявление typedef определяет безымянный класс или перечисление, первое имя typedef для типа класса или перечисления, объявленного этим объявлением, является именем typedef для целей связывания этого типа.
Например, в typedef struct { /* ... */ } S;, S является именем typedef для целей связывания. Определённый таким образом тип класса или перечисления имеет внешнее связывание (если только он не находится в безымянном пространстве имён).
| Безымянный класс, определённый таким образом, должен содержать только конструкции, совместимые с C. В частности, он не должен
и все вложенные классы также должны удовлетворять этим требованиям (рекурсивно). | (начиная с C++20) |
Примечания
| Псевдонимы типов предоставляют ту же функциональность, что и объявления typedef, но используют другой синтаксис и также применимы к именам шаблонов. | (начиная с C++11) |
Ключевые слова
Пример
// simple typedef
typedef unsigned long ulong;
// the following two objects have the same type
unsigned long l1;
ulong l2;
// more complicated typedef
typedef int int_t, *intp_t, (&fp)(int, ulong), arr_t[10];
// the following two objects have the same type
int a1[10];
arr_t a2;
// beware: the following two objects do not have the same type
const intp_t p1 = 0; // int *const p1 = 0
const int *p2;
// common C idiom to avoid having to write "struct S"
typedef struct { int a; int b; } S, *pS;
// the following two objects have the same type
pS ps1;
S* ps2;
// error: storage-class-specifier cannot appear in a typedef declaration
// typedef static unsigned int uint;
// typedef can be used anywhere in the decl-specifier-seq
long unsigned typedef int long ullong;
// more conventionally spelled "typedef unsigned long long int ullong;"
// std::add_const, like many other metafunctions, use member typedefs
template<class T>
struct add_const
{
typedef const T type;
};
typedef struct Node
{
struct listNode* next; // declares a new (incomplete) struct type named listNode
} listNode; // error: conflicts with the previously declared struct name
// C++20 error: "struct with typedef name for linkage" has member functions
typedef struct { void f() {} } C_Incompatible;
Отчёты об ошибках
Следующие отчёты об ошибках, изменяющие поведение, были применены задним числом к ранее опубликованным стандартам C++.
| Отчёт об ошибке | Применён к | Опубликованное поведение | Корректное поведение |
|---|---|---|---|
| CWG 576 | C++98 | typedef не разрешалось использовать во всём определении функции | разрешено в теле функции |
| CWG 2071 | C++98 | typedef мог присутствовать в объявлении, не содержащем декларатора | теперь запрещено |
См. также
Документация по C для Typedef declaration |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/language/typedef