0

I would like to be able to use an if statement that looks something like this:

if (input == Positive)
{
    // Do something
}

To be actually doing something that looks like this:

if (input == "yes" ||input ==  "Yes" ||input ==  "YES" ||input ==  "Ya" ||input ==  "ya" (etc all the rest of positive words/ways to say yes))
{
    // Do something
}

I was thinking I would keep my code in a static library (though I don't know much about them so feel free to correct me if there is a better way) so that I can access it from any future program I use and I don't have to copy-paste this same code over and over. Is there any way to do this? Or something similar to this?

Thanks very much in advance :)

Quentin
  • 60,592
  • 7
  • 125
  • 183
  • 2
    Just to mention few: you may also consider `if (isPositive(input))` but if that's not what you reeaaally want then you might create an `Input` class (let's say) with an overloaded `==` operator (and `Positive` has to be an instance of that class). Note that if you have a list `std::vector` of words then a simple `find()` might do. – Adriano Repetti Sep 18 '19 at 12:26
  • 2
    @Habitate C++ can't `switch` on non-integral types. – Quentin Sep 18 '19 at 12:28
  • @Quentin oh yeah, totaly forgot – Rokas Višinskas Sep 18 '19 at 12:37
  • @AdrianoRepetti Solution is the C++ way to do this. Put the code you don't want to repeat in a function, and then call that function when needed. You could use something like [this](https://stackoverflow.com/questions/43020246/simulating-pythons-in-in-c) to make it Pythony but it can/will cause you issues later on down the road. – NathanOliver Sep 18 '19 at 12:38
  • Note that achieving the syntax you wish for, and wrapping that in a reusable component are two different questions. The latter depends on which C++ toolchain you are using, which you haven't mentioned. – Quentin Sep 18 '19 at 12:40
  • You can use regular expression to solve this problem statement. – abhiarora Sep 18 '19 at 12:45
  • @phuclv, that applies to integers rather than strings - the bitmasking solutions there aren't applicable here. – Toby Speight Sep 18 '19 at 12:55
  • @TobySpeight there are various solutions there. And of course there are countless number of duplicates: [C++ multiple strings inside an if statement](https://stackoverflow.com/q/43484761/995714), [Check for multiple values when using comparison operators](https://stackoverflow.com/q/11583592/995714), [Check if string is in string (list of strings)](https://stackoverflow.com/q/14515274/995714) – phuclv Sep 18 '19 at 12:59
  • @NathanOliver I agree, that's why the "reeaally". I'd personally feel confused to see `==` used as `in` too. – Adriano Repetti Sep 18 '19 at 13:01

1 Answers1

2

There are many ways to test for inclusion. The most natural is to use a set:

#include <set>
#include <string>
    static const std::set<std::string> positive_answers =
        { "yes", "Yes", "YES", "Ya", "ya" };

    if (positive_answers.count(input) > 0) {

        // Do something
    }

Here's a full program version of the above:

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

int main()
{
    std::string input = "YES";

    static const std::set<std::string> positive_answers =
        { "yes", "Yes", "YES", "Ya", "ya" };

    if (positive_answers.count(input) > 0) {
        std::cout << "Agreed\n";
    } else {
        std::cout << "Disagreed\n";
    }
}

You might consider using a variadic template:

template<typename T, typename... U>
bool is_in(T candidate, U... positives)
{
    const std::set<std::string> positive_answers{{positives...}};
    return positive_answers.count(candidate) > 0;
}

used like this:

    if (is_in(input, "yes", "Yes", "YES", "Ya", "ya"))

That can work, but be careful if input is a C-style string (char*), as that will use a pointer's comparison function.

Toby Speight
  • 25,191
  • 47
  • 61
  • 93