34 votes

Raccourcissez la condition pour vérifier que x n'est pas l'un des quatre nombres

Est-il possible de raccourcir la condition pour cette déclaration if?

 int x;
if(x != 3 && x != 8 && x != 87 && x != 9){
        SomeStuff();
    }
 

Je pense à quelque chose comme ça:

 if(x != 3,8,87,9){}
 

Mais j'ai essayé ça et ça ne marche pas. Dois-je simplement écrire le long chemin?

43voto

Alexis Pierru Points 287

Si vous voulez savoir si un entier est dans un ensemble donné d’entiers, utilisez alors std::set :

 std::set<int> accept { 1, 4, 6, 8, 255, 42 };
int x = 1;

if (!accept.count(x))
{
    // ...
}
 

32voto

1201ProgramAlarm Points 4465

Juste pour être complet, je vais utiliser un interrupteur:

 switch (x) {
    case 1:
    case 2:
    case 37:
    case 42:
        break;
    default:
        SomeStuff();
        break;
}
 

Bien que ce soit assez détaillé, il n'évalue x qu'une fois (s'il s'agit d'une expression) et génère probablement le code le plus efficace de toute solution.

29voto

Lingxi Points 163

Voici ma solution en utilisant un modèle variadique. Les performances d'exécution sont aussi efficaces que l'écriture manuelle x != 3 && x != 8 && x != 87 && x != 9 .

 template <class T, class U>
bool not_equal(const T& t, const U& u) {
  return t != u;
}

template <class T, class U, class... Vs>
bool not_equal(const T& t, const U& u, const Vs... vs) {
  return t != u && not_equal(t, vs...);
}

int main() {
  std::cout << not_equal( 3, 3, 8, 87, 9) << std::endl;
  std::cout << not_equal( 8, 3, 8, 87, 9) << std::endl;
  std::cout << not_equal(87, 3, 8, 87, 9) << std::endl;
  std::cout << not_equal( 9, 3, 8, 87, 9) << std::endl;
  std::cout << not_equal(10, 3, 8, 87, 9) << std::endl;
}
 

14voto

DarioP Points 1350

Et ça:

 #include <iostream>
#include <initializer_list>
#include <algorithm>

template <typename T>
bool in(const T t, const std::initializer_list<T> & l) {
    return std::find(l.begin(), l.end(), t) != l.end();
}

int main() {
  std::cout << !in(3, {3, 8, 87, 9}) << std::endl;
  std::cout << !in(87, {3, 8, 87, 9}) << std::endl;
  std::cout << !in(10, {3, 8, 87, 9}) << std::endl;
}
 

ou surcharger le operator!= :

 template<typename T>
bool operator!=(const T t, const std::vector<T> & l) {
    return std::find(l.begin(), l.end(), t) == l.end();
}

int main() {
  std::cout << ( 3!=std::vector<int>{ 3, 8, 87, 9}) << std::endl;
  std::cout << ( 8!=std::vector<int>{ 3, 8, 87, 9}) << std::endl;
  std::cout << (10!=std::vector<int>{ 3, 8, 87, 9}) << std::endl;
}
 

Malheureusement pour le moment, les analyseurs n'aiment pas avoir initializer_list comme argument des opérateurs . Il n'est donc pas possible de supprimer std::vector<int> dans la deuxième solution.

5voto

CroCo Points 666

Si vous ne voulez pas de répéter cette condition, à maintes reprises, puis l'utilisation de la macro.

#include <iostream>

#define isTRUE(x, a, b, c, d)  ( x != a && x != b && x != c && x != d ) 

int main() 
{
    int x(2);
    std::cout << isTRUE(x,3,8,87,9) << std::endl;

    if ( isTRUE(x,3,8,87,9) ){
        // SomeStuff();
    }
    return 0;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X