Manuel approprié logique La mise en œuvre de XOR dépend du degré d'imitation du comportement général des autres opérateurs logiques ( ||
y &&
) avec votre XOR. Il y a deux choses importantes à propos de ces opérateurs : 1) ils garantissent une évaluation en court-circuit, 2) ils introduisent un point de séquence, 3) ils évaluent leurs opérandes une seule fois.
L'évaluation XOR, comme vous le comprenez, ne peut pas être court-circuitée puisque le résultat dépend toujours des deux opérandes. Le 1 est donc hors de question. Mais qu'en est-il de 2 ? Si vous ne vous préoccupez pas de 2, alors avec une évaluation normalisée (c.-à-d., une évaluation XOR), il est possible d'obtenir un résultat qui dépend des deux opérandes. bool
) opérateur de valeurs !=
fait le travail de XOR en termes de résultat. Et les opérandes peuvent être facilement normalisés avec unary !
si nécessaire. Ainsi, !A != !B
implémente le XOR approprié à cet égard.
Mais si vous vous souciez du point de séquence supplémentaire, ni l'un ni l'autre !=
ni par bit ^
est la façon correcte d'implémenter XOR. Une façon possible de faire XOR(a, b) correctement pourrait ressembler à ceci
a ? !b : b
C'est en fait ce qui se rapproche le plus de la fabrication d'un XOR fait maison "semblable" à ||
y &&
. Cela ne fonctionnera, bien sûr, que si vous implémentez votre XOR comme une macro. Une fonction ne fera pas l'affaire, puisque le séquencement ne s'appliquera pas aux arguments de la fonction.
Quelqu'un pourrait dire, cependant, que la seule raison d'avoir un point de séquence à chaque fois &&
y ||
est de supporter l'évaluation court-circuitée, et donc XOR n'en a pas besoin. Cela a du sens, en fait. Pourtant, il est intéressant d'envisager d'avoir un XOR avec un point de séquence au milieu. Par exemple, l'expression suivante
++x > 1 && x < 5
a un comportement défini et un résultat spécifique en C/C++ (en ce qui concerne le séquençage au moins). On peut donc raisonnablement s'attendre à ce que la même chose se produise avec les fonctions logique XOR, comme dans
XOR(++x > 1, x < 5)
tandis qu'un !=
-Le XOR basé sur l'inverse n'a pas cette propriété.
59 votes
En fait, Jim, ce n'est pas la seule différence entre & et && par exemple... 1 && 2 est Vrai. mais 1 & 2 => 0. Pour cette raison, je pense que le "court-circuitage" est juste une propriété qu'ils ont par hasard. La logique est la caractéristique la plus importante...
7 votes
Sans compter que 2 && 3 == vrai, mais 2 & 3 == 2.
1 votes
David Thomley : Eh bien, oui, mais 2 ==> vrai, donc c'est bon... Souviens-toi, il n'y a pas vraiment de booléens...
14 votes
@BrianPostow : En fait, en C++, il y en a.
7 votes
Comme indiqué ci-dessous, voici la réponse de Dennis Ritchie qui explique pourquoi il n'existe pas : c-faq.com/misc/xor.dmr.html
0 votes
Qu'est-ce qui ne va pas avec l'utilisation du
^
opérateur de type bitwise ? Par exemplea = 2, b = 5, c = 5
y(a == b ^ a ==c)
donnera le résultat escompté.0 votes
Intéressant que ^ fonctionne bien pour les bools avec g++/clang++/VSC++, mais la réponse de @greg-hewgill est l'approche la plus correcte pour les xor logiques (j'ai dit tout de go "duh" à l'instant où j'ai vu sa réponse).
0 votes
Je pense qu'un opérateur ^^ serait utile. Les autres solutions proposées ci-dessous sont plutôt kludgy.