Raccourci pour vérifier l’égalité à plusieurs possibilités

Dupliquer possible:
C ++ comparant un groupe de valeurs à une donnée

J’ai besoin de vérifier l’égalité dans une boucle for en C ++, mais la boucle doit fonctionner pour x, ce qui correspond à plusieurs possibilités.

Par exemple, à l’heure actuelle, j’ai quelque chose de similaire à:

if(x==a || x==b || x==c || x==d || x==e || x==f || x==g || x==h) { //loop body } 

Mais avec le numéro que j’ai, cela semble compliqué et je me demandais s’il existait un moyen abrégé de dire “si (x == (une de ces))” ou si tout écrire était la seule option.

Merci!

Merci pour votre question. Maintenant que j’ai trouvé une solution (et une solution élégante, j’ose le dire), je vais l’utiliser moi-même.

Contrairement aux solutions avec std :: find: a) sera-t-il déroulé jusqu’à N comparaisons en temps de compilation b) fonctionnera avec tous les types auxquels X peut être comparé

 struct TagAnyOf {}; template  std::tuple  AnyOf (Args&&... args) { return std::tuple  (TagAnyOf(), std::forward(args)...); } template  struct CompareToTuple { static bool compare (const X& x, const Tuple& tuple) { return x == std::get (tuple) || CompareToTuple::compare (x, tuple); } }; template  struct CompareToTuple  { static bool compare (const X& x, const Tuple& tuple) { return false; } }; template  bool operator == (const X& x, const std::tuple& any) { typedef std::tuple  any_of_type; return CompareToTuple ::value-1>::compare (x, any); } 

Usage

 int main() { int x = 1; if (x == AnyOf (1, 2, 3, 4)) { std::cout << "Yes!" << std::endl; } else { std::cout << "No!" << std::endl; } if (x == AnyOf (4, 3, 2, 1)) { std::cout << "Yes!" << std::endl; } else { std::cout << "No!" << std::endl; } if (x == AnyOf (2, 3, 4, 5)) { std::cout << "Yes!" << std::endl; } else { std::cout << "No!" << std::endl; } return 0; } 

Pensez à utiliser une fonction prenant une liste d’initialisation (c’est une fonctionnalité de c ++ 11).
le premier paramètre serait la valeur de gauche (x dans votre cas) et les autres parameters seront des valeurs de droite.


Voici un exemple qui accomplit la tâche à l’aide de modèles.

 #include  #include  #include  template bool Test(T const& test, std::initializer_list const& values){ return std::find(std::begin(values), std::end(values), test) != std::end(values); } int main(){ char var1 = 'a'; char var2 = 'a'; char var3 = 'b'; char var4 = 'c'; char var5 = 'd'; if (Test(var1,{var2,var3,var4,'o',var5})){ std::cout << "true. at least one is equivelent" << std::endl; }else{ std::cout << "false. none are equivelent" << std::endl; } if (Test(var1,{var3,var4,var5})){ std::cout << "true. at least one is equivelent" << std::endl; }else{ std::cout << "false. none are equivelent" << std::endl; } return EXIT_SUCCESS; } 

Si vous faites cela avec des classes, assurez-vous de surcharger l'opérateur '! ='.

edit: erreur corrigée. signalé par GManNickG

Je me demandais s’il y avait un moyen abrégé de dire “si (x == (aucun de ces))”

Oui, la norme vous donne std::find et std::find_if pour répondre exactement à cette question:

 int a=3,b=5,c=6,d=7; std::array vals{{a,b,c,d}}; // or std::vector int x=5; bool foundit= (end(vals) != std::find_if(begin(vals), end(vals),x ); 

Tu auras besoin de

 #include  #include  

Vous pouvez également utiliser std::initializer_list booleans{a,b,c,d}; au lieu de vector ou de array

Si vos conditions sont plus compliquées, vous pouvez utiliser find_if:

  bool foundit= (end(vals) != std::find_if(begin(vals), end(vals), [&x](const int &v){return v*(v+x)