4

私はいくつかの古いコード (たまたまテキスト ゲーム) で作業していて、パターンを置き換えたいと考えていました。

strcasecmp(variable, "something") == 0 || strcasecmp(variable, "something else") == 0

より良いもので

in_list(variable, "something", "something else")

可変関数が適切だと思いました。しかし、マンページを見ると、いつ引数を使い果たしたかを知る方法がないことがわかりました (va_arg未定義の動作が発生したときに呼び出す)。では、どうすればこれを処理できますか?

この制限を回避する方法があるかもしれません。#defineリストの最後にある種のセンチネルを配置して、それを確認できるかもしれませんが、それはエレガントではないようです. ハックのように感じますが、これを 1、2、... の引数を持つマクロのファミリに置き換えることができると思いますが、これはハックのように感じます。

これを行う正しい方法は何ですか?型を使用するようにプログラムを書き直す気はなく、sstringで行き詰まっているとしchar*ます。

4

1 に答える 1

6

C++11 の機能を使用できると仮定すると、std::set初期化子リストをサポートするコレクション型 (例: ) を関数に持たせることができるので、次のようなものを使用できます。

in_list(variable, {"something", "something else", "yet a third thing"});

編集:ここに簡単なデモがあります:

#include <string>
#include <set>
#include <iostream>

bool in_list(std::string const &value, std::set<std::string> const &list) {
    return list.find(value) != list.end();
}

int main(){
    std::cout << std::boolalpha << in_list("true", {"this", "is", "a", "true", "statement"}) << "\n";

    std::cout << in_list("false", {"this", "is", "a", "true", "statement"});
    return 0;
}

これは g++ 4.7.0 で問題なくコンパイルされ、期待される出力が生成されます。

true
false

はい、そうしない理由がなければ、std::set当面の仕事にとって合理的な選択です。char *vs.に関する懸念がある限り、は からの暗黙の変換をサポートしてstd::stringいるため、(上記で行ったように) 関数にa を渡すことができ、自動的に に変換されます。言い換えれば、(ほとんどの) 他のコードは単に を渡すことができ、このコードがそれを と見なす細かな詳細について心配する必要はありません。std::stringchar *char *std::stringchar *std::string

于 2012-05-11T03:36:35.897 に答える