4

我正在使用一些旧代码(碰巧是文本游戏)并想替换模式

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

有更好的东西,比如

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

我认为可变参数函数是合适的。但是当我查看联机帮助页时,我发现无法判断您何时用完了参数(va_arg在导致未定义行为时调用)。那么我该如何处理呢?

也许有一些方法可以绕过这个限制。也许我可以#define在列表末尾添加某种哨兵,以便我可以检查它,尽管它看起来不优雅。我想我可以将其替换为具有 1、2、... 参数的宏系列,直到某个合理的限制,尽管这感觉像是一个 hack。

这样做的正确方法是什么?假设我不愿意重写程序以使用该string类型并且我坚持使用char*s。

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而言:std::string支持从 的隐式转换char *,因此您可以将 a 传递char *给函数(正如我在上面所做的那样),它将std::string自动转换为。换句话说,(大多数)其他代码可以通过char *,而不必担心该代码将其视为的次要细节std::string

于 2012-05-11T03:36:35.897 回答