There is such a thing as overkill. If you are only interested in boolean values, then explicitly convert to boolean before using XOR. Otherwise you'd have to explicitly define what it means to convert an object to boolean.
For example, as
helios posited: what would be the value of
string1 ^^ string2
? Strings are not booleans, so you would have to define the operation to mean something. If you want a boolean result defined on the non-emptiness of a string, then be explicit about that:
!string1.empty() ^^ !string2.empty()
The same is true for
string1 && string2
What does that mean?
!string1.empty() && !string2.empty()
means something, because it is explicit about how a boolean value is extracted from a string.
While it would be nice to have a logical xor function, remember that the only real difference between the logical and bitwise functions are whether or not the operands are first converted to boolean. That is:
a && b
is the same as
(bool)a & (bool)b
is the same as
(a != 0) & (b != 0)
which is how it is actually implemented.
The same is true for ||.
There is no ^^, but since && and || are really syntactic sugar for bitwise operations on bool-converted operands, it is just as understandable to use them without the sugar:
1 2 3
|
(bool)a & (bool)b
(bool)a | (bool)b
(bool)a ^ (bool)b
|
Note again that (bool) is only applicable to integer argument types (and those that define an
operator bool() const
member function).
int,
char, and
bool are the only integer types defined by C++. (
enums and pointers are type-promoted to
int.)
float and
double are not integer types.
struct,
class, and
union are not integer types.
Arrays are not integer types.
Those are all the types there are.
Alas.