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
  • 62,093
  • 7
  • 131
  • 191
  • 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
  • 27,591
  • 48
  • 66
  • 103
  • You can also use `count` instead of `find` - it returns 1 when found and 0 otherwise. This will avoid the long-winded `== .end()` syntax. – anatolyg Sep 18 '19 at 12:49
  • Of course - thanks! A set knows that count is at most 1, so there's no inefficiency as there would be with a vector or list. – Toby Speight Sep 18 '19 at 12:51
  • Why not an unordered_set? – Tharwen Sep 18 '19 at 12:52
  • @Tharwen - no good reason; either is as good as the other for a small set of alternatives such as this. – Toby Speight Sep 18 '19 at 12:53
  • ...on the other hand `count` wont stop counting once it found the first positive, though for 5 elements that shouldnt really matter – 463035818_is_not_an_ai Sep 18 '19 at 13:46
  • 2
    @formerlyknownas_463035818: as I commented, a set's `count()` *does* "stop counting" once it's determined whether or not the item is present in the set. You may be thinking of the `std::count()` function in ``, which would examine every member of the set. Don't use that. – Toby Speight Sep 18 '19 at 13:52
  • ah sorry, I read anatolygs comment, but understood it only now – 463035818_is_not_an_ai Sep 18 '19 at 13:55