Boost logo

Boost :

Subject: Re: [boost] PR: Remove safe_bool idiom from boost.tribool
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2018-05-19 17:22:53


On Sat, May 19, 2018 at 7:09 PM, Robert Ramey via Boost
<boost_at_[hidden]> wrote:
> On 5/19/18 8:18 AM, Andrey Semashev via Boost wrote:
>>
>> On Sat, May 19, 2018 at 1:17 AM, Robert Ramey via Boost
>> <boost_at_[hidden]> wrote:
>>>
>>>
>>> One idea which has been tried is to use C++11 "explicit" as a substitute
>>> from the safe_bool idiom. Unfortunately this breaks legacy code.
>>>
>>> bool f(x) {
>>> return tribool(true); // fails
>>> }
>>>
>>> So this is not a great solution either.
>>
>>
>> C++11 explicit conversion operators don't support this use case, so if
>> it works with the safe_bool idiom then it is either a bug or an
>> unavoidable unfortunate limitation of the emulation.
>
> I don't think that one can conclude that because C++11 expicit conversion
> operators don't support a use case that it's a bug. The question is whether
> conversion to bool from tribool makes some sort of sense. I think it does -
> regardless of what C++11 actually does.

Explicit conversion operators are the evolution of the safe_bool
idiom. In other words, it represents what we tried to achieve with
safe_bool (and possibly failed in some aspects).

>> User's code should be updated in this case.
>
> This code has been in usage for 15 years. One can just start using the
> explicit bool conversion and then break tons of code - some of it very old.
> In one case (QT) this change generated 100's of syntax errors in existing
> code.

I'm not saying this is going to be easy, but the change would be for
the better, IMHO. We could offer some transition period.

>> There are also other accidents that are intended to be prevented by
>> safe_bool/explicit conversion operators. For example:
>>
>> void foo(bool f);
>>
>> foo(t);
>
> Right - I get this. I think this is a good conversion to support. That is
> why my change supports implicit conversion from tribool to bool.

I tried using tribool in my projects multiple times and every time I
dropped it soon after the start in favor of an enum or something
similar. The reason is that I can never readily tell how the
conversion to bool works. The example above illustrates this rather
well - I can never say what foo will receive if t is indeterminate.

>> Some accidents are also prevented by the recent changes to the
>> language. For example, increment/decrement operations on bool are
>> deprecated since C++11 and removed since C++17.
>
> Hmmm - I did not know that. Since one of the main motivations of safe_bool
> is to inhibit this behavior, and it will shortly be inhibited by a C++17 in
> any case, it supports my argument for eliminating safe_bool idiom from
> tribool.

I don't think it does. The change removes ambiguous or plain wrong
operations on bool, and explicit conversion (and, similarly,
safe_bool) are there for the same reason, only for user's types.

>>> b) it's an especially a bad idea for tribool.
>>>
>>> The motivating concept behind tribool is that of some sort of "extended"
>>> bool. The naming suggests that it acts like a bool. But since we've used
>>> he
>>> safe_bool idiom, it doesn't any more. That is we can't use a tribool
>>> anywhere a bool is used. So if we use operator bool we'll get a tribool
>>> which acts like a bool - even when the original usage of bool was a bad
>>> idea
>>> according to a) above. But at least we have the same behavior for
>>> tribool
>>> and bool which is a lot more intuitive and less confusing.
>>>
>>> Also, changing to operator bool () will address the current problem with
>>> GCC
>>> not supporting a constexpr version of tribool.
>>>
>>> Accordingly, I've submitted this PR to change the implementation of
>>> tribool
>>> to avoid the safe_bool idiom.
>
> and implement a normal operator bool instead!
>
>> I would say I agree that the conversion operator is not a good idea
>> with regard to tribool.
>
> Hmmm - I'm proposing adding and ordinary conversion operator to convert
> tribool to bool. How can you agree with me while saying it's not a good
> idea?

Maybe I misunderstood you, but you said yourself that this is "a bad
idea for tribool". Sorry if I misunderstood.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk