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.
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:Edit: Here’s a quick demo:
This compiles cleanly with g++ 4.7.0, and produces the expected output:
And yes, absent a reason to do otherwise,
std::setwould be a reasonable choice for the job at hand. As far as your concern overchar *vs.std::stringgoes:std::stringsupports implicit conversion fromchar *, so you can pass achar *to the function (as I’ve done above) and it’ll be converted tostd::stringautomatically. In other words, (most) other code can just passchar *, and not worry about the minor detail that this code views it asstd::string.