C ++中的逻辑XOR运算符?

有这样的事吗? 这是我第一次遇到它的实际需求,但我没有看到在Stroustrup中列出的一个。 我打算写:

// Detect when exactly one of A,B is equal to five. return (A==5) ^^ (B==5); 

但是没有^^运算符。 我可以在这里使用按位,并得到正确的答案(不pipe机器表示真假)? 我从不混合&&&||| ,所以我犹豫要用^^^来做这个。

我会更舒适的写我自己的bool XOR(bool,bool)function。

!=运算符为bool值提供此目的。

对于真正的逻辑异或操作,这将起作用:

 if(!A != !B) { // code here } 

正确的手动逻辑 XOR实现取决于你想用你的异或模拟其他逻辑运算符( ||&& )的一般行为。 这些运营商有两个重要的事情:1)他们保证短路评估,2)他们引入一个序列点,3)他们只评估一次操作数。

如您所知,XOR评估不能被短路,因为结果总是取决于两个操作数。 所以1是没有问题的。 但是2呢? 如果你不关心2,那么用规范化的(即bool )值操作符!=就结果而言,XOR的工作。 操作数可以很容易地用一元规范化! ,如有必要。 因此!A != !B在这方面实现了正确的XOR。

但是,如果你关心额外的序列点,那么既不是按位,也不是实现异或的正确方法。 正确执行XOR(a,b)的一种可能方式可能如下所示

 a ? !b : b 

这实际上是尽可能靠近自制XOR与“相似”的 和&& 。 当然,如果将XOR实现为macros,这只会起作用。 函数不会做,因为sorting不适用于函数的参数。

有人可能会说,每个&&||都有一个序列点的唯一原因 是支持短路评估,因此XOR不需要一个。 实际上这是有道理的。 然而,值得考虑的是在中间有一个序列点的XOR。 例如,下面的expression式

 ++x > 1 && x < 5 

已经在C / C ++中定义了行为和具体的结果(至less在测序方面)。 所以,可以合理地期望从用户定义的逻辑 XOR相同,如在

 XOR(++x > 1, x < 5) 

而基于!=的XOR没有这个属性。

还有另一种方法来做XOR:

 bool XOR(bool a, bool b) { return (a + b) % 2; } 

哪些显然可以certificate通过工作:

 #include <iostream> bool XOR(bool a, bool b) { return (a + b) % 2; } int main() { using namespace std; cout << "XOR(true, true):\t" << XOR(true, true) << endl << "XOR(true, false):\t" << XOR(true, false) << endl << "XOR(false, true):\t" << XOR(false, true) << endl << "XOR(false, false):\t" << XOR(false, false) << endl << "XOR(0, 0):\t\t" << XOR(0, 0) << endl << "XOR(1, 0):\t\t" << XOR(1, 0) << endl << "XOR(5, 0):\t\t" << XOR(5, 0) << endl << "XOR(20, 0):\t\t" << XOR(20, 0) << endl << "XOR(6, 6):\t\t" << XOR(5, 5) << endl << "XOR(5, 6):\t\t" << XOR(5, 6) << endl << "XOR(1, 1):\t\t" << XOR(1, 1) << endl; return 0; } 

异或运算符不能被短路; 即只通过评估其左手操作数就无法预测XORexpression式的结果。 因此,没有理由提供^^版本。

有一些很好的代码发布,比!!!!更好的解决了这个问题

请注意,我必须添加BOOL_DETAIL_OPEN / CLOSE,以便在MSVC 2010上工作

 /* From: http://groups.google.com/group/comp.std.c++/msg/2ff60fa87e8b6aeb Proposed code left-to-right? sequence point? bool args? bool result? ICE result? Singular 'b'? -------------- -------------- --------------- ---------- ------------ ----------- ------------- a ^ b no no no no yes yes a != b no no no no yes yes (!a)!=(!b) no no no no yes yes my_xor_func(a,b) no no yes yes no yes a ? !b : b yes yes no no yes no a ? !b : !!b yes yes no no yes no [* see below] yes yes yes yes yes no (( a bool_xor b )) yes yes yes yes yes yes [* = a ? !static_cast<bool>(b) : static_cast<bool>(b)] But what is this funny "(( a bool_xor b ))"? Well, you can create some macros that allow you such a strange syntax. Note that the double-brackets are part of the syntax and cannot be removed! The set of three macros (plus two internal helper macros) also provides bool_and and bool_or. That given, what is it good for? We have && and || already, why do we need such a stupid syntax? Well, && and || can't guarantee that the arguments are converted to bool and that you get a bool result. Think "operator overloads". Here's how the macros look like: Note: BOOL_DETAIL_OPEN/CLOSE added to make it work on MSVC 2010 */ #define BOOL_DETAIL_AND_HELPER(x) static_cast<bool>(x):false #define BOOL_DETAIL_XOR_HELPER(x) !static_cast<bool>(x):static_cast<bool>(x) #define BOOL_DETAIL_OPEN ( #define BOOL_DETAIL_CLOSE ) #define bool_and BOOL_DETAIL_CLOSE ? BOOL_DETAIL_AND_HELPER BOOL_DETAIL_OPEN #define bool_or BOOL_DETAIL_CLOSE ? true:static_cast<bool> BOOL_DETAIL_OPEN #define bool_xor BOOL_DETAIL_CLOSE ? BOOL_DETAIL_XOR_HELPER BOOL_DETAIL_OPEN 

使用一个简单的:

 return ((op1 ? 1 : 0) ^ (op2 ? 1 : 0)); 

我使用“xor”(它似乎是一个关键字;在Code :: Blocks中 ,至less它是粗体),就像你可以使用“和”而不是&&和“或”来代替||

 if (first xor second)... 

是的,这是按位。 抱歉。

下面是我认为你在C ++中编写XOR比较的方法:

 bool a = true; // Test by changing to true or false bool b = false; // Test by changing to true or false if (a == !b) // THIS IS YOUR XOR comparison { // do whatever } 

certificate

 XOR TABLE ab XOR --- --- --- TTF TFT FTT FFF a == !b TABLE ab !ba == !b --- --- --- ------- TTFF TFTT FTFT FFTF 

certificate是,对input和输出的详尽研究表明,在两个表中,对于每个input集合,两个表格中的结果总是相同的。

所以,原来的问题是如何写:

 return (A==5) ^^ (B==5) 

答案是

 return (A==5) == !(B==5); 

或者,如果你喜欢,写

 return !(A==5) == (B==5); 
 #if defined(__OBJC__) #define __bool BOOL #include <stdbool.h> #define __bool bool #endif static inline __bool xor(__bool a, __bool b) { return (!a && b) || (a && !b); } 

它按照定义工作。 条件是检测是否使用Objective-C ,它是要求BOOL而不是bool(长度不同!)