2016-02-26 2 views
-2

Je suis 99% sûr que cela ne fonctionnera pas, mais que 1% restants me tracasseNotation de notation C++ if - Est-ce équivalent?

int x; 

    //is this if statement 

    if(x == 1, 5, 7) 
    { 
    //do something here 
    } 
    //equivalent to this if statement 

    if((x == 1) || (x == 5) || (x == 7)) 
    { 
    //do something here 
    } 
+1

Vous auriez pu l'essayer pour voir si cela fonctionne. – Barmar

+2

C'est la première fois que j'ai vu quelqu'un essayer cela avec des virgules. Ils essaient généralement quelque chose comme 'if (x == 1 || 5 || 7)'. – Barmar

+0

Si vous voulez un entier rapide "X est en jeu Y" opération (où l'ensemble Y est connu à la compilation), utilisez une instruction 'switch', car il est compilé à une table de hachage littérale (une branche-table), qui est incroyablement rapide. – Dai

Répondre

5

Non, c'est pas totalement équivalent.

if(x == 1, 5, 7) 

appelle la comma operator, qui se terminera efficacement dans la dernière valeur à cause de , a la priorité la plus basse:

if(7) 

depuis déplier avec parenthèses devrait ressembler

if(((x == 1), 5), 7) 

tout

if((x == 1) || (x == 2) || (x == 7)) 

vérifie si x est égal à 1, 2 ou 7.

+2

opérateur de virgule a la plus basse priorité, voir http://en.cppreference.com/w/cpp/language/operator_precedence et http://ideone.com/rxhki1 – Anedar

+0

@Anedar THX pour votre tweak, je ne suis pas sûr entre-temps. Je pense que c'est plus clair maintenant. –

1

Ils ne sont pas égaux. Lorsque vous écrivez comme

if(x == 1, 5, 7) 
    { 
    //do something here 
    } 

il se traduit essentiellement en

if(7) 
    { 
    //do something here 
    } 

qui sera toujours vrai dans le cas où le numéro dans le bloc de condition est un nombre non nul.

Exemple 1:

int main() 
{ 
    int x=10; 
    if(x==1,5,7) 
     cout<<"hello"<<endl; 
    return 0; 
} 

Ici, la sortie est "bonjour", parce que 7 est traitée comme une vraie variable booléenne.

Exemple 2:

int main() 
    { 
     int x=10; 
     if(x==1,5,0) 
      cout<<"hello"<<endl; 
     return 0; 
    } 

Ici, il n'y a pas de sortie parce que 0 est considéré comme une variable fausse booléenne.

+0

Vous pouvez suggérer la raison de l'expression évaluant à 7, telle que l'opérateur virgule. –

0

En ce qui concerne une solution plus rapide discuté dans la section des commentaires de l'OP, voici une solution « rapide »:

Si vous avez un grand nombre de comparaisons constantes d'observer, une déclaration switch est plus rapide que personne if(x == 1) instructions comme il est compilé à une table-branche (une sorte de hashtable directement dans le code du programme, lui donnant O(1) lookup), mais il est possible que les compilateurs existants déjà optimiser if(x==1||x==2||x==3...) à une table de branche aussi.

bool xIsInSet = false; 
switch(x) { 
    case 0: case 1: case 2: case 3: 
    case 4: case 5: case 6: case 7: // add a case for each literal comparison 
     xIsInSet = true; // no `break` needed, there's only 1 case. 
} 
if(xIsInSet) { 
    // do stuff 
} 

Cela peut être inline à un lambda qui est invoquée immédiatement pour éliminer xIsInSet:

if([&x]() -> bool { 
    switch(x) { case 0: case 1: case 2: case 3: return true; } 
    return false; }() 
) { 
    // do stuff 
} 

Malheureusement modèles variadique de 11 C++ ne nous laissez pas ajouter dynamiquement case déclarations et le piratage à l'aide un préprocesseur #define est possible - si cela ne vous dérange pas d'utiliser une bibliothèque de métaprogrammation.Une meilleure alternative pourrait être un #include en ligne d'un fichier généré par votre script de construction. Ce qui serait encore plus simple serait un moyen d'obtenir en quelque sorte la sortie standard d'un autre programme (par exemple, si nous pouvions faire #include '.\generateCasesFor.sh 1 2 5 10 12', hélas pas encore).