On 22/05/2018 13:25, Robert Ramey wrote:
which to me looks like a perfectly reasonable thing to do. But using explicit would create a compile time error.
I disagree.
I am not sure what you are disagreeing with here, unless you intended to disagree with yourself?
No, that's a perfect example of terrible code that should absolutely generate a compiler error. A narrowing conversion (from a source type that can express more values than the destination type) should absolutely *never* under any circumstances occur implicitly.
I think that tribool is/was designed to promote this and in this case I find it useful and natural.
No, it wasn't. The somewhat-implicit bool conversion (safe_bool) was expressly for use within if statements, as demonstrated in the documentation (https://www.boost.org/doc/libs/1_67_0/doc/html/tribool/tutorial.html). Nowhere in this documentation will you find implicitly returning a tribool as a bool. Note that explicit bool is also designed to handle the case where used in a conditional context in an implicit fashion, exactly the same as safe_bool. Explicit bool also avoids the unintended side effects of implicit bool conversions, such as promotion to integer (as pointed out by Peter) and unintended narrowing when returning or passing parameters. Implicitly returning a tribool as a bool should be forbidden for exactly the same reasons as returning an int64_t as an int32_t -- you are losing information, and unless you have explicitly indicated that this was intended (presumably because you know things that the compiler does not), it should be assumed to be a bug, perhaps as a result of a recent change of types or just an oversight.
I don't think explicit was created to fix safe_bool. In general I support usage of explicit. But in this case I don't think it's a good match.
The explicit keyword itself was not. But "explicit operator bool" itself was, as part of C++11. (You can use the same keywords pre-C++11 but it will not have the correct effect.) (Specifically, there's a loophole that allows implicit use of explicit bool conversions when in a conditional context such as an if statement where only a bool expression is valid.) Thus "explicit" by itself disables all the unintended implicit usages of the conversion, and C++11 then enables the one intended implicit use.
Right. But then I'm imposing your view point on many users programs which already exist. You're basically changing the intention of tribool. You may well have a good argument that the very idea of tribool is a bad idea, that it should never have been made the way it was and that no one should use it, but that ship sailed long, long ago. It's not relevant here.
No, you're the one trying to change the intent. Implicit bool conversions are a behavioural downgrade and will only serve to introduce bugs. I can't believe this is even an argument.