On Mon, Jun 24, 2013 at 7:40 PM, Greg Marr <
greg...@gmail.com> wrote:
>
> On Monday, June 24, 2013 4:37:47 AM UTC-4, Jim Smith wrote:
>>
>> std::bool_intermediate for states that are not true or false. ... Also, std::bool_intermediate take into account the superposition of the two boolean states.
>
>
> This sounds exactly like std::optional<bool>.
I think `optional<bool>` has confusing semantics to be used for
tri-value logic. I'll call the third value "third", just for
exposition. Consider:
// I would normally not use == true, but I think it is worth for clarity here
optional<bool> a = true;
assert(bool(a) == true);
assert(bool(!a) == false);
assert(*a == true);
optional<bool> b = false;
assert(bool(a) == true);
assert(bool(!a) == false);
assert(*a == false);
auto third = none;
optional<bool> c = third;
assert(bool(c) == false);
assert(bool(!c) == true);
// *c is UB
With this `bool(a)` or any contextual conversion to bool, like
`if(a)`, means "Is `a` not the third value?"/
`bool(!a)` means "Is `a` the third value?"
And `*a` means "assuming `a` is not the third value, is it true?"
The question "Is `a` false?" would have to be `!*a`, which is actually
"assuming `a` is not the third value, is it true?"
So a three-way if with optional<bool> would look like:
if(!a) {
// third value
} else if(*a) {
// true
} else {
// false
}
I prefer something like boost::tribool.
tribool a = true;
assert(bool(a) == true);
assert(bool(!a) == false);
tribool b = false;
assert(bool(a) == false);
assert(bool(!a) == true);
tribool c = third;
assert(bool(c) == false);
assert(bool(!c) == false);
With this `bool(a)` means "Is `a` true?", and `bool(!a)` means "Is `a`
false?". The third value, not being true nor false yields "no" for
both queries.
So a three-way if looks like:
if(a) {
// true
} else if(!a) {
// false
} else {
// third value
}
Another thing to notice is that `operator!` works as expected with
tribool: the negation of true is false, and the negation of false is
true. The negation of an indeterminate value is indeterminate (it acts
a bit like NaN in floating point arithmetic; call it not-a-boolean ;).
With optional<bool> the negation of false is false.
I prefer to restrict my usage of optional<bool> for incidental
occurrences in generic code, and not as a tri-valued boolean. I don't
need it often, but I wouldn't mind having a tribool type in the
standard library, as long as it is not some "object-oriented"
nonsense.