13

int関数を使用してプログラムの最後に呼び出されるを返す関数を登録しようとしていatexit()ます。(具体的には、endwin()ncurses の関数です。)

しかし、関数atexit()へのポインタが必要なので、問題が発生しました。void私は次のことを試しました:

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

しかし、関数から関数へのstatic_castingは許可されていないようです。intvoid

私が達成しようとしていることはまったく可能ですか? はいの場合、どのように?

注:関数の戻り値は無視してもかまいません。


編集:ラムダ関数も作成しようとしましたが、これは私が望むことをしているようです:

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

ラッパー/転送機能と比較して、これは良い解決策ですか? (それ以外は、C++11 を必要とし、別の関数を転送することだけを目的とする新しい関数を定義することを避けます。)

4

3 に答える 3

23

関数ポインタは変換できません。転送機能を登録するだけです:

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

extern "C"質問に C++ のタグを付けたので、C++ で転送関数を定義する場合は、適切な言語リンケージを持つように宣言する必要があります。

于 2015-02-14T14:10:44.993 に答える
11

現在の C++ 標準では、ラムダがおそらくこれに対する最良の解決策です。

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

これで、別の関数を転送することだけを目的として、まったく新しい名前付き関数を定義する必要がなくなりました。


また、ある日、プログラムの終了時にさらに関数を呼び出す必要があると判断した場合は、次の新しい呼び出しでそれらを定義できますatexit()

atexit(anotherCleanupFunction);

または、それらをラムダ本体に追加するだけです。

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

ただし、複数の関数を に登録するatexit()場合は、それらすべての関数を保持する別のラッパー関数を使用する方が適切な解決策になる場合があります。ただし、正解はありません。適切で明確なコードを記述してください。(atexit()関数呼び出しでいっぱいのラムダによる with の呼び出しは、かなり乱雑に見える可能性があります。)

于 2015-02-14T15:36:17.627 に答える