Що означає цей вислів typedef?


76

На довідковій сторінці C ++ вони містять кілька прикладів typedef, і я намагаюся зрозуміти, що вони означають.

// simple typedef
typedef unsigned long mylong;


// more complicated typedef
typedef int int_t, *intp_t, (&fp)(int, mylong), arr_t[10];

Тож простий typedef (перше оголошення) я розумію.

Але що вони заявляють з другим (повторене нижче)?

typedef int int_t, *intp_t, (&fp)(int, ulong), arr_t[10];

Що саме (&fp)(int, mylong)означає?


47
Слід зазначити, що написання однолінійного typedef goo, як це, є дуже поганою практикою програмування, оскільки її важко читати і жодної переваги від цього немає. Тож якщо ви читаєте це і ніколи не бачили подібних typedefs, будь ласка, не починайте використовувати цей синтаксис.
Лундін,

3
@Lundin Я не згоден. Помістивши їх усі в один рядок, стає зрозуміло, що ви маєте намір мати на увазі, що всі вони стосуються одного базового типу. За визначенням.
Містер Лістер,

9
@MrLister Якщо ви пишете їх кожен в окремому рядку один за одним, кожен рядок починатиметься, typedef some_type ...і у вас є кілька таких рядків, ваші наміри дуже чіткі, і немає місця для синтаксичних ковзань. Набагато читабельніше.
Лундін,

2
@Lundin Це може бути питанням смаку, тому я не впевнений, чи нам потрібно вступати в дискусію з цього приводу.
Містер Лістер,

Відповіді:


96

Це оголошення декількох typedefs одночасно, так само, як ви можете оголосити кілька змінних одночасно. Усі вони засновані на int, але деякі модифікуються на складові типи.

Розділимо це на окремі декларації:

typedef int int_t;              // simple int
typedef int *intp_t;            // pointer to int
typedef int (&fp)(int, ulong);  // reference to function returning int
typedef int arr_t[10];          // array of 10 ints

5
Протягом багатьох років програмування на C ++ я цього не знав! Я думаю, мій інструктор не вважав, що це потрібно навчитися, і я нічого про це не знайшов. +1
Джон Одом

17
Ваш інструктор мав рацію. Це важче для читання, це функція, яку ви не повинні використовувати.
Plutor

41
typedef int int_t, *intp_t, (&fp)(int, mylong), arr_t[10];

еквівалентно:

typedef int int_t;
typedef int *intp_t;
typedef int (&fp)(int, mylong);
typedef int arr_t[10];

Насправді є подібний приклад у стандарті C ++ 11:

C ++ 11 7.1.3 специфікаторtypedef

A typedef-name не вводить новий тип так, як це робить classдекларація (9.1) або enumдекларація. Приклад: after

typedef int MILES , * KLICKSP ;

конструкцій

MILES distance ;
extern KLICKSP metricp ;

всі правильні декларації; тип відстані - це int, який - metricpце “вказівник на int”. —Кінцевий приклад


13
Наскільки я розумію, відповідь правильна. Чому голос негативний?
Діпто

32

Якщо у вас є cdeclкоманда, ви можете використовувати її для демістифікації цих оголошень.

cdecl> explain int (&fp)(int, char)
declare fp as reference to function (int, char) returning int
cdecl> explain int (*fp)(int, char)
declare fp as pointer to function (int, char) returning int

Якщо у вас цього немає cdecl, ви зможете встановити його звичайним способом (наприклад, у системах типу Debian, використовуючи sudo apt-get install cdecl).


@athos Fromsudo apt-get install cdecl
Amarghosh

о, це не для Windows?
афон

0

(&fp)(int, mylong)Частина є посилання на функцію. Не рекомендується, щоб програмісти використовували функції саме typedefз тієї причини, з якої ви задаєте це питання. Це бентежить інших людей, які дивляться на код.

Я здогадуюсь, що вони використовують typedefщось приблизно так:

typedef unsigned long mylong; //for completeness
typedef int (&fp)(int, mylong);
int example(int param1, mylong param2);

int main() {
     fp fp_function = example;
     int x = fp_function(0, 1);
     return 0;
}

int example(int param1, mylong param2) {
     // does stuff here and returns reference
     int x = param1;
     return x;
}

Відредаговано відповідно до коментаря Брайана:

int(&name)(...)є функцією опорного називається name(функція повертає Int)

int &name(...)- це функція, що називається name поверненням посилання на int

Посилання на функцію, яка повертає intпосилання, виглядатиме приблизно так: typedef int &(&fp)(int, mylong)(це компілюється в програмі, але поведінка не перевірена).


3
Ні, int&(int, mylong)це інший тип int(&)(int, mylong). Перший - це функція, що повертає посилання на int. Останнє є посиланням на функцію, що повертається int. Посилання на функції неясні і не дуже корисні, але вони існують в C ++.
Брайан

Звичайно, це дещо складно, але яка альтернатива? Не використовуєте typedef? Вам усе ще потрібен тип, але без typedef вам доведеться явно використовувати той самий тип функції скрізь, де це потрібно, що в десять разів більше заплутує і, звичайно, схильне до помилок. Замість того, щоб отримувати один typedef правильно, програміст повинен отримати правильний тип у багатьох місцях.
gnasher729

2
"рекомендується" ким? Typedefs для покажчиків функцій дуже часто використовуються в численних API API для зворотних викликів, а використання typedef означає, що функція, яка приймає покажчик функції як її параметр, є набагато зручнішою для читання. Якщо ви не можете використовувати лямбди на C ++, вказівники функцій typedefs є набагато кращим стилем кодування, ніж використання їх безпосередньо, якщо ви реалізуєте, наприклад, асинхронний API.
uliwitness 03.03.14

-7

typedef визначає новий тип для використання у вашому коді, як скорочення.

typedef typename _MyBase::value_type value_type;
value_type v;
//use v

typename тут повідомляє компілятору, що value_type - це тип, а не об’єкт усередині _MyBase.

the :: - область дії типу. Це щось на зразок "є в", тому value_type "є в" _MyBase. або також може розглядатися як містить.

Можливий дублікат: C ++ - значення виразу, що поєднує typedef та typename


10
Ця відповідь не корисна. У запитанні чітко зазначається, що вони розуміють основну концепцію typedef(яку ви пояснили), але були здивовані більш складною (якої ви навіть не торкалися).
mirabilos
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.