Składnia c dla funkcji zwracających Wskaźniki funkcji
Zwróć uwagę na następujący typ:
typedef int (*f1)(float);
typedef f1 (*f2)(double);
typedef f2 (*f3)(int);
f2
jest funkcją zwracającą wskaźnik funkcji. To samo dotyczy f3
, ale typ funkcji, wskaźnik do którego zwraca f3
, to f2
. Jak mogę zdefiniować f3
bez typedefs? Wiem, że typedefs są czystszym i łatwiejszym do zrozumienia sposobem definiowania f3
. Jednak moim zamiarem jest tutaj lepsze zrozumienie składni C.
6 answers
Zacznij od deklaracji dla f1
:
int (*f1)(float);
Chcesz, aby f2
był wskaźnikiem do funkcji zwracającej f1
, więc zastąp f1
w powyższej deklaracji deklaracją dla f2
:
int (* f1 )(float);
|
+-----+-----+
| |
v v
int (*(*f2)(double))(float);
Deklaracja brzmi jak
f2 -- f2
*f2 -- is a pointer
(*f2)( ) -- to a function
(*f2)(double) -- taking a double parameter
*(*f2)(double) -- returning a pointer
(*(*f2)(double))( ) -- to a function
(*(*f2)(double))(float) -- taking a float parameter
int (*(*f2)(double))(float) -- returning int
Powtarzasz proces dla f3
:
int (*(* f2 )(double))(float);
|
+---+----+
| |
v v
int (*(*(*f3)(int))(double))(float);
Który czyta się jako
f3 -- f3
*f3 -- is a pointer
(*f3)( ) -- to a function
(*f3)(int) -- taking an int parameter
*(*f3)(int) -- returning a pointer
(*(*f3)(int))( ) -- to a function
(*(*f3)(int))(double) -- taking a double parameter
*(*(*f3)(int))(double) -- returning a pointer
(*(*(*f3)(int))(double))( ) -- to a function
(*(*(*f3)(int))(double))(float) -- taking a float parameter
int (*(*(*f3)(int))(double))(float); -- returning int
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-25 18:07:35
W C++ cud szablonów może to nieco ułatwić.
#include <type_traits>
std::add_pointer<
std::add_pointer<
std::add_pointer<
int(float)
>::type(double)
>::type(int)
>::type wow;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-25 17:36:28
Tak samo jak w przypadku typedef, tylko umieszczasz swoją definicję funkcji zamiast jej nazwy.
Oto jak wygląda f2
:
typedef int (*(*f2)(double))(float);
Możesz zrobić f3
jako ćwiczenie, skoro zakładam, że to praca domowa;)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-25 17:26:19
Można to zrobić, ale będzie to bardzo mylące. Typedef są po to, aby ułatwić pisanie i czytanie tego krótkiego kodu.
Funkcja f
, która nie pobiera argumentów i zwraca wskaźnik funkcji int (*)(float)
prawdopodobnie byłaby czymś w rodzaju (niesprawdzonym):
int (*f())(float);
Następnie dla reszty musisz dodawać nawias, aż będzie wyglądał jak lisp.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-25 17:32:50
Poznaj regułę prawo-lewo :
Reguła "prawo-lewo" jest całkowicie regularną regułą do rozszyfrowywania C deklaracje. Może być również przydatny w ich tworzeniu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-16 09:05:52
Użycie std::function
:
typedef std::function<int(float)> f1;
typedef std::function<f1(double)> f2;
typedef std::function<f2(int)> f3;
Lub
typedef std::function<std::function<std::function<int(float)>(double)>(int)> f3;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-01 17:38:46