Pytanie Co oznacza ta instrukcja typedef?


Na stronie referencyjnej C ++ podają przykłady typedef i próbuję zrozumieć, co one oznaczają.

// simple typedef
typedef unsigned long mylong;


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

Tak rozumiem prosty typedef (pierwsza deklaracja).

Ale co deklarują z drugim (powtórzonym poniżej)?

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

Szczególnie co robi (&fp)(int, mylong) oznaczać?


76
2018-02-27 07:23


pochodzenie


Należy zauważyć, że pisanie taktyki typu linku typedef jest bardzo kiepską praktyką programistyczną, ponieważ jest trudne do odczytania i nie ma z tego żadnej korzyści. Więc jeśli czytasz to i nigdy nie widziałem takich czcionek, nie zaczynaj używać tej składni. - Lundin
@Lundin Nie zgadzam się. Umieszczenie ich wszystkich w jednej linii jasno pokazuje, że masz zamiar mieć wszystkie odnoszą się do tego samego typu bazy. Zgodnie z definicją. - Mr Lister
@MrLister Jeśli napiszesz je w osobnej linii po sobie, każda linia zacznie się typedef some_type ... i masz kilka takich linii, twoje intencje są bardzo jasne i nie ma miejsca na skrypty składni. O wiele bardziej czytelny. - Lundin
@Lundin Może to być kwestia gustu, więc nie jestem pewien, czy musimy wziąć udział w dyskusji na ten temat. - Mr Lister


Odpowiedzi:


Deklaruje kilka typów na raz, tak jak możesz zadeklarować kilka zmiennych naraz. Wszystkie są oparte na typach int, ale niektóre są modyfikowane na typy złożone.

Podzielmy go na osobne deklaracje:

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

97
2018-02-27 07:30



Przez całe lata programowania C ++ tego nie wiedziałem! Wydaje mi się, że mój instruktor nie wierzył, że trzeba się tego nauczyć i nigdy nic nie znalazłem. +1 - John Odom
Twój instruktor miał rację. To jest trudniejsze do odczytania, to funkcja, którą ty nie powinien posługiwać się. - Plutor


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

jest równa:

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

W rzeczywistości istnieje podobny przykład w standardzie C ++ 11:

C ++ 11 7.1.3 The typedef specyficzny

ZA typedef-name nie wprowadza nowego typu w sposób a class deklaracja (9.1) lub enum deklaracja ma.Przykład: po

typedef int MILES , * KLICKSP ;

konstrukcje

MILES distance ;
extern KLICKSP metricp ;

wszystkie są poprawnymi deklaracjami; typ odległości to int metricp to "wskaźnik do int"-End przykład


41
2018-02-27 07:26



Według mnie odpowiedź jest prawidłowa. Dlaczego głosowanie jest negatywne? - Dipto


Jeśli masz cdecl polecenie, możesz użyć go do demistyfikacji tych deklaracji.

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

Jeśli nie masz cdecl, powinieneś być w stanie zainstalować go w zwykły sposób (np. w systemach typu Debian, używając sudo apt-get install cdecl).


32
2018-02-27 07:32



gdzie to robi cdecl polecenie pochodzi? - athos
@athos Od sudo apt-get install cdecl - Amarghosh
och, więc to nie jest dla Windowsa? - athos


The (&fp)(int, mylong) część reprezentuje odniesienie do funkcji. Nie jest zalecane, aby programiści korzystali z funkcji typedef z tego samego powodu, zadajesz to pytanie. To myli innych ludzi patrząc na kod.

Zgaduję, że używają tego typedef w czymś takim:

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;
}

Edytowane zgodnie z komentarzem Briana:

int(&name)(...) jest odniesienie do funkcji nazywa name (funkcja zwraca int)

int &name(...) jest funkcją o nazwie name  zwracając odwołanie do int

Odniesienie do funkcji, która zwraca int odniesienie wyglądałoby mniej więcej tak: typedef int &(&fp)(int, mylong) (to kompiluje się w programie, ale zachowanie nie jest testowane).


0
2018-02-27 07:37



Nie, int&(int, mylong) jest inny od int(&)(int, mylong). Pierwsza to funkcja zwracająca odwołanie do int. Ta ostatnia jest odniesieniem do funkcji zwracającej int. Odwołania do funkcji są niejasne i mało przydatne, ale istnieją w C ++. - Brian
Pewnie, że to trochę skomplikowane, ale jaka jest alternatywa? Nie używasz typedef? Nadal potrzebujesz typu, ale bez typedef musisz jawnie używać tego samego typu funkcji wszędzie, gdzie jest potrzebny, co jest dziesięć razy bardziej mylące i oczywiście podatne na błędy. Zamiast tego, aby uzyskać prawidłowy typ, programista musi uzyskać typ w wielu miejscach. - gnasher729
"jest zalecane" przez kogo? Typedefs dla wskaźników funkcji są bardzo często używane w wielu API C dla wywołań zwrotnych, a użycie parametru typedef oznacza, że ​​funkcja, która przyjmuje wskaźnik funkcji jako jego parametr, jest znacznie bardziej czytelna. O ile nie można używać lambd C ++, wskaźnik funkcyjny typedefs jest IMO o wiele lepszym stylem kodowania niż użycie ich bezpośrednio, jeśli np. Wdrożysz np. asynchroniczny interfejs API. - uliwitness


typedef definiuje nowy typ do użycia w twoim kodzie, jak skrót.

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

nazwa_tabeli tutaj pozwala kompilatorowi wiedzieć, że value_type jest typem, a nie obiektem wewnątrz _MyBase.

:: jest zakresem typu. Jest to trochę jak "jest w", więc value_type "jest w" _MyBase. lub może być również uważany za zawierający.

Możliwy duplikat: C ++ - znaczenie instrukcji łączącej typedef i typename


-7
2018-02-27 07:34



Ta odpowiedź nie jest pomocna. Pytanie jasno stwierdza, że ​​rozumie on podstawową koncepcję a typedef (co wyjaśniłeś), ale zaintrygował cię bardziej złożony (którego nawet nie dotknąłeś). - mirabilos