|
Boost : |
Subject: Re: [boost] PR: Remove safe_bool idiom from boost.tribool
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2018-05-22 06:17:54
On 22/05/2018 17:23, Robert Ramey wrote:
> On 5/21/18 7:05 PM, Gavin Lambert wrote:
>> 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.
>
> I doesn't have to since void * (safe_bool) can be converted implicitly
> as bool. And there are many, many cases where this is done. You might
> not think this is a great idea, but it's a fact. These programs will
> fail to compile if you change safe_bool to explicit.
The intended purpose of safe_bool implicitly converting to bool was for
use in conditional expression contexts.
That it permitted other narrowing conversions is not intended and is
unfortunate.
> Now you're re-hashing the design of tri-bool. It works the way it has
> for many, many years. Its consistent with other components such as
> std::optional which do the same thing and what many people are happy
> with.
std::optional was added after C++11 and as such uses explicit bool. It
does not have implicit conversions.
Older versions of boost::optional did use safe_bool, but have since been
updated to use explicit bool where compiler-supported (via macro
BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT).
So both of these support my argument, not yours.
(Perhaps the better PR would be to make tribool use that macro, defined
in boost/core/explicit_operator_bool.hpp)
> actually "explicit" can be applied to conversion operators of all types
> - intrinsic as well as user defined. I'm sure there was no intent to
> think in terms of "explicit bool" as some special situation.
I'm referring to the contextual bool conversion mentioned later on. It
is indeed a special situation.
>> (You can use the same keywords pre-C++11 but it will not have the
>> correct effect.)
>
> Hmmm - I was not aware that "explicit" could be applied to conversion
> operators before C++11.
True, I misspoke; I was thinking of explicit constructors, which don't
apply here as it's the wrong conversion direction.
> LOL - Right. That's the root of the whole discussion. At some point
> long ago everyone thought these implicit conversions were a good idea.
> I presume they still do as we have optional which include implicit
> conversions to bool and I'm sure there are some more.
Implicit widening conversions can still be a good idea. Implicit
narrowing conversions never are. And again optional does not do what
you claim.
>> Thus "explicit" by itself disables all the unintended implicit usages
>> of the conversion, and C++11 then enables the one intended implicit use.
>
> Hmmm - I thought that C++11 enables implicit conversion of any integer
> or pointer to a bool for purposes of if, when etc.
Anything that is explicitly convertible to bool, yes. That doesn't
invalidate my point.
> maybe for components like optional, but I don't see it happening for
> tribool. continuing to permit tribool implicitly convert to bool - as it
> currently - won't introduce any more bugs than it does currently - if
> there are any.
This is incorrect, as Peter already pointed out.
Additionally, you should consider the effect on future code -- it's not
really a great argument to claim that a safety railing is no longer
necessary because nobody has fallen off the cliff while the safety
railing was there.
> b) move to explicit when supported. - which eliminates the compile error
> but makes behavior dependent to the C++ standard used to compile. It
> will also break a lot of current user code.
This is the only option that makes sense to me. If that breaks user
code, it is a net positive effect because that code was already broken
-- and it is trivial to correct it where actually intended.
This is no different than when boost::optional switched to explicit
bool, to use your own example correctly.
> c) implement inplicit conversion to bool. This breaks no current code
> and resolves the current constexpr issue. It does permit t + u where t
> and u are results of bool conversions. This will be fixed automatically
> for C++17.
As far as I am aware, this is not correct; bool is still implicitly
convertible to int in all versions of C++.
(And https://en.cppreference.com/w/cpp/language/implicit_conversion agrees.)
I welcome proof otherwise; although that still would not change my
opinion as it doesn't help those using pre-C++17 compilers.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk