Правильна логічна реалізація XOR залежить від того, наскільки тісно ви хочете імітувати загальну поведінку інших логічних операторів ( ||
і &&
) з вашим XOR. У цих операторів є дві важливі речі: 1) вони гарантують оцінку короткого замикання, 2) вводять точку послідовності, 3) оцінюють свої операнди лише один раз.
Як ви розумієте, оцінка XOR не може бути короткою, оскільки результат завжди залежить від обох операндів. Отже, 1 не викликає сумніву. А як щодо 2? Якщо вам не байдуже 2, bool
оператор із нормалізованими (тобто ) значеннями !=
виконує роботу XOR з точки зору результату. І операнди можна легко нормалізувати з одинарними !
, якщо це необхідно. Таким чином !A != !B
реалізується належний XOR в цьому відношенні.
Але якщо ви хвилюєтесь додатковою точкою послідовності, ні, !=
ні бітовий ^
спосіб не є правильним способом реалізації XOR. Один з можливих способів правильно зробити XOR (a, b) може виглядати наступним чином
a ? !b : b
Це насправді настільки близько, як ви можете зробити так, щоб зробити домашній XOR «подібним» до ||
та &&
. Це буде працювати, звичайно, якщо ви реалізуєте XOR як макрос. Функція не буде виконувати, оскільки послідовність не застосовуватиметься до аргументів функції.
Хто - то може сказати , однак, що єдиною причиною , що має точку послідовності на кожному &&
і ||
є підтримка короткозамкненим оцінки, і , таким чином , XOR не потрібен. Це має сенс, власне. Тим не менш, варто подумати про те, що в середині є XOR з точкою послідовності. Наприклад, наступний вираз
++x > 1 && x < 5
визначає поведінку та конкретний результат у C / C ++ (щонайменше щодо послідовності). Отже, можна з розумом очікувати того ж від визначеного користувачем логічного XOR, як у
XOR(++x > 1, x < 5)
в той час як !=
XOR на базі не має цього властивості.