La corretta implementazione XOR logica manuale dipende da quanto si desidera imitare il comportamento generale di altri operatori logici ( ||
e &&
) con il proprio XOR. Ci sono due cose importanti su questi operatori: 1) garantiscono la valutazione del corto circuito, 2) introducono un punto di sequenza, 3) valutano i loro operandi una sola volta.
La valutazione XOR, come capisci, non può essere messa in corto circuito poiché il risultato dipende sempre da entrambi gli operandi. Quindi 1 è fuori discussione. Ma che dire di 2? Se non ti importa di 2, allora con bool
valori normalizzati (cioè ) l'operatore !=
fa il lavoro di XOR in termini di risultato. E gli operandi possono essere facilmente normalizzati con unario !
, se necessario. In tal modo, !A != !B
implementa l'XOR corretto in tal senso.
Ma se ti preoccupi del punto di sequenza aggiuntivo, né !=
né bit a bit ^
è il modo corretto di implementare XOR. Un modo possibile per eseguire correttamente XOR (a, b) potrebbe essere il seguente
a ? !b : b
Questo è in realtà il più vicino possibile a rendere uno XOR fatto in casa "simile" a ||
e &&
. Questo funzionerà, ovviamente, solo se si implementa XOR come macro. Una funzione non funziona, poiché il sequenziamento non si applica agli argomenti della funzione.
Qualcuno potrebbe dire, però, che l'unica ragione di avere un punto di sequenza a ciascun &&
ed ||
è per supportare la valutazione corto-circuito, e quindi XOR non ne ha bisogno. Questo ha senso, in realtà. Tuttavia, vale la pena considerare di avere un XOR con un punto sequenza nel mezzo. Ad esempio, la seguente espressione
++x > 1 && x < 5
ha un comportamento definito e risultati specifici in C / C ++ (almeno per quanto riguarda il sequenziamento). Quindi, ci si potrebbe ragionevolmente aspettare lo stesso dallo XOR logico definito dall'utente , come in
XOR(++x > 1, x < 5)
mentre un !=
XOR a base non ha questa proprietà.