Boost logo

Boost :

Subject: Re: [boost] [optional] operator<(optional<T>, T) -- is it wrong?
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2014-11-29 18:58:27


Le 29/11/14 22:13, Gottlob Frege a écrit :
> On Sat, Nov 29, 2014 at 5:58 AM, Vicente J. Botet Escriba
> <vicente.botet_at_[hidden]> wrote:
>> We have worked a lot with implicit conversion as C++98 did have explicit
>> ones. I would say that the conversion should be explicit by default.
>> Implicit conversion should be allowed only when there is a sub-type
>> relationships <: between the types. This sub-type relationship should
>> satisfy:
>>
>> Anti-symetric:
>> If we have types R, S such that R <: S with implicit conversions from R to S
>> , the conversion from S to R can not be implicit (no implicit cycles),
>> however there should be an explicit conversion from S to R (coercion).
>>
> Does the coercion need to be via explicit constructor, or can it be a
> function? ie shared_ptr::get() ?
I have no problem with the name of the coercion function. However, when
things are uniform we can add generic checkers.
The case of smart pointer is weird case as the stored value is a pointer
to the value :( As if we had SmartPtr<T*>).
Note that you have also the explicit pointer conversion. The problem is
the syntax as the wrapped type is T*

   typedef int* int_raw_ptr;
   int* p = new int(24);
   assert(int_raw_ptr(unique_ptr<int>(p)) == p);

> As "test cases", I think shared_ptr and unique_ptr need explicit
> from-ptr constructors (for safety),
Tony, maybe you could turn you safety concern on a a new rule/guideline ;-)
> but (IMO) dumb_ptr does not.
No observed_ptr (old dump_ptr) has an explicit constructor from the
pointer :(
>
> Do your rules agree?

No. No smart pointer can be considered as a sub-type of the pointed type.

If we want to allow implicit conversion between wrapped types and
wrapper types my initial rules should be extended. But I don't think we
should do it. I think we need an explicit conversion in this case.

As you maybe know, I'm all for the convert function [1], so that you
state explicitly that you are doing a conversion to the target type.

   void f(dump_ptr<int>);

   int* p= new int(24);
   f(p); // compile fails
   f(convert(p)); // just works without any mention to an explicit
dump_ptr<int> conversion

I would even prefer a variation of [2]

   f( explicit {p} );

where here explicit is considered as a replacement of the type
parameter, in this case dump_ptr<int>.

[1] N3521 - About convert() utility function
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3521.html
[2] 4074 - Let return {expr} Be Explicit, Revision 2
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4074.pdf
>>>> Currently we have std::less, not std::order and the STL ordered
>>>> containers
>>>> are using as default comparator std::less. So let define
>>>> std::less<optional<T>> using std::less<T>.
>>>>
>>> Yes. We currently have that much - std::less<optional<T>> is built
>>> with std::less<T>, not op<(T,T).
>>> Even if only for the sake of pointers. On almost-non-existent
>>> hardware, (and maybe future hardware).
>>>
>>>
>> I'm missing the wording for the definition of std::less<optional<T>> in
>> function of std::less<T>. Could you point me where this is described?
>>
> Grrrrrrrrrrrrr. I give up. It was there when I last argued for it.
> Not sure when it got removed. :-(
>
I have already signaled it to std-proposals ML. I hope this will be an
editorial issue.

Best,
Vicente


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