On Sat, May 19, 2018 at 7:09 PM, Robert Ramey via Boost
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
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.