Подтвердить что ты не робот

Как зарегистрировать функцию non-void с помощью atexit()?

Я пытаюсь зарегистрировать функцию, которая возвращает int для вызова в конце программы с помощью функции atexit(). (В частности, функция endwin() из ncurses.)

Но так как atexit() нужен указатель на функцию void, я столкнулся с проблемой. Я попробовал следующее:

static_cast<void (*)()>(endwin)

но static_cast от функции int до функции void, похоже, не разрешено.

Я пытаюсь сделать все возможное, и если да, то как?

Примечание. Я хочу просто игнорировать возвращаемое значение функции.


Изменить: Я также попытался создать функцию лямбда, которая, кажется, делает то, что я хочу:

atexit([]{ endwin(); });

Это хорошее решение по сравнению с функцией обертки/пересылки? (Кроме того, он нуждается в С++ 11 и избегает определения новой функции, единственной целью которой является просто пересылка другой функции.)

4b9b3361

Ответ 1

Указатели функций не могут быть преобразованы. Просто зарегистрируйте функцию пересылки:

#ifdef __cplusplus
extern "C"
#endif
void endwin_wrapper() { endwin(); }
...
atexit(endwin_wrapper);

Поскольку вы отметили свой вопрос С++: если вы определяете функцию пересылки в С++, вам нужно объявить ее extern "C" для правильной языковой привязки.

Ответ 2

С текущим стандартом С++ lambda, вероятно, является лучшим решением для этого:

atexit([]{ endwin(); });

Теперь нет необходимости определять целую новую именованную функцию с единственной целью просто перенаправить другую функцию.


И если вы однажды решите, что вам нужно больше функций, вызываемых при выходе из программы, вы можете либо определить их с помощью нового вызова atexit():

atexit(anotherCleanupFunction);

или вы можете просто добавить их в тело лямбда:

atexit([]{
  anotherCleanupFunction();
  endwin();
});

Тем не менее, когда у вас есть несколько функций для регистрации в atexit(), тогда отличная функция-обертка для хранения всех этих функций. Там нет ни одного правильного ответа, просто напишите хороший и понятный код. (Вызов atexit() с помощью лямбды, полной вызовов функций, может выглядеть довольно грязно.)

Ответ 3

"Я пытаюсь сделать что-то вообще, и если да, то как?"

Вы просто пишете свою собственную функцию-обертку для endwin() и зарегистрируете ее

void myEndwin() {
    endwin();
}