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
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)