Оператор 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++.
| DR | Применено к | Поведение, как опубликовано | Правильное поведение |
|---|---|---|---|
| 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/w/cpp/language/typedef