Рекурсивное объявление указателя функции в C
Я хотел бы объявить функцию, которая возвращает указатель на функцию того же типа.
Я хотел бы использовать его для реализации государственных машин, как показано ниже:
typedef event_handler_t (*event_handler_t)(event_t*); // compilation error
event_handler_t state2(event_t* e);
event_handler_t state1(event_t* e) {
switch(e->type) {
//...
case SOME_EVENT:
return state2;
//...
}
}
event_handler_t state2(event_t* e) {
switch(e->type) {
//...
case OTHER_EVENT:
return state1;
//...
}
}
//...
event_handler_t event_handler;
//...
event_handler(&e);
//...
Мне удается обойти ошибку слияния с использованием структур следующим образом:
typedef struct event_handler {
struct event_handler (*func)(event_t *);
} event_handler_t;
Но это делает более сложным условие возврата:
event_handler_t state2(event_t* e) {
{
event_handler_t next_handler = {NULL};
switch(e->type) {
//...
case OTHER_EVENT:
next_handler.func = state1;
break;
//...
}
return next_handler;
}
Интересно, есть ли лучший способ создания таких указателей на функции в c.
Ответы
Ответ 1
Это невозможно сделать в C: функция не может вернуть указатель на себя, так как объявление типа рекурсивно расширяется и никогда не заканчивается. См. Эту страницу для объяснения: http://www.gotw.ca/gotw/057.htm
Обходной путь, описанный на вышеприведенной странице, означает возврат void (*) ()
вместо правильно заданного указателя функции; ваше обходное решение, возможно, немного опрятно.
Ответ 2
Это обсуждается в книге Херба Саттера Более исключительный С++, пункт 32, где ответ кажется (для C) "не без использования приведений". Для С++ можно с обычным введением класса предоставить некоторую дополнительную косвенность.