Variadic string-comparison

c++, variadic-functions

Solution

Assuming you can use C++11 features, I'd have the function take a collection type (e.g., `std::set`) that supports initializer lists, so you could use something like:

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

Edit: Here's a quick demo:

#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;
}

This compiles cleanly with g++ 4.7.0, and produces the expected output:

true
false

And yes, absent a reason to do otherwise, `std::set` would be a reasonable choice for the job at hand. As far as your concern over `char *` vs. `std::string` goes: `std::string` supports implicit conversion from `char *`, so you can pass a `char *` to the function (as I've done above) and it'll be converted to `std::string` automatically. In other words, (most) other code can just pass `char *`, and not worry about the minor detail that this code views it as `std::string`.

Problem

I was working with some old code (a text game, as it happens) and wanted to replace the pattern ``` strcasecmp(variable, "something") == 0 || strcasecmp(variable, "something else") == 0 ``` with something nicer, like ``` in_list(variable, "something", "something else") ``` I thought a variadic function would be appropriate. But when I looked at the manpage I saw that there's no way to tell when you've run out of arguments (calling `va_arg` when you have results in undefined behavior). So how can I handle this? Maybe there's some way to get around this limitation. Maybe I can `#define` some kind of sentinel at the end of the list so I can check for that, though it seems inelegant. I suppose I could just replace it with a family of macros with 1, 2, ... arguments up to some reasonable limit, though this feels like a hack. What's the right way to do this? Suppose I'm not willing to rewrite the program to use the `string` type and that I'm stuck with `char*`s.

Original source