1

mf_ptrがクラスのメンバ関数ポインタの typedef であるとします。そして、流れるコードがあります:

map<string, mb_ptr> cmd_table;
cmd_table["exit"] = &class_name::exit;
string cmd;
while (cin >> cmd){
    (this->*cmd_table[cmd])();
}

では、while ループを終了するには、関数 exit() をどのように定義すればよいでしょうか?

4

3 に答える 3

6

いくつかのオプションがあります:

  1. exit 関数で例外を発生させ、while ループでキャッチします。

  2. while ループを終了するかどうかに関係なく、すべての関数がブール値を返すようにします。

于 2012-06-13T03:19:41.677 に答える
2

次のようなことができます。

while (cin >> cmd && !class_name::exitLoop){
    (this->*cmd_table[cmd])();
}

class_name::exitLoopによって true に設定される場所class_name::exit()

私は個人的に行きます:

while(cin >> cmd && cmd != "exit") {
    (this->*cmd_table[cmd])();
}
于 2012-06-13T03:22:44.623 に答える
0

使用できます(上記のように指定した方法):

class_name::exit(void) { cin.setstate(eofbit); ... }
...
while(cin >> cmd)
    (this->*cmd_table[cmd])();

この場合、ループはコマンドの処理exitに終了します(次の反復ラウンド>>は失敗します)。

より複雑にしたい場合は、カスタムストリーム抽出演算子を作成できます。

friend istream & operator>>(istream & is, class_name::CmdExecutorClass &comm)
{
    string cmd;
    cin >> cmd;
    if (cmd == "exit")
        cin.setstate(eofbit);
    else
        (comm.table[cmd])();
    return is;
}

私が見ることができる利点は、次のように簡単に書けることです。

while (cin >> cmd);

エラー/不明なコマンドを処理できます(たとえば、キーの要素が存在しない場合std::map<...>::operator[] にマップに追加します-それはあなたが望むものではないかもしれません)。
ただし、クラスを作成するにはかなりの接着剤も必要です(埋め込みの「マスター」クラスから参照CmdExecutorを渡すためのコンストラクターまたはテンプレートなど)。table[]単純なケースでは、やり過ぎです。

編集:また、クロージング cineofビットの設定が効果的に行われること)も望ましくない可能性があることを追加する必要があります。failビット (後で再度クリアできる) の方が、おそらくより適切なオプションです。

于 2012-06-13T08:46:00.430 に答える