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 05:58:18


Le 28/11/14 20:22, Gottlob Frege a écrit :
> On Thu, Nov 27, 2014 at 8:08 PM, Vicente J. Botet Escriba
> <vicente.botet_at_[hidden]> wrote:
>>>> 0 - std::less should be same as op<
>>>> (I think we all agree here, actually, which is why we should have
>>>> std::order)
>> Only if op< id defined.
> Do you mean only *the same* if op< is defined, or only *exists* if op<
> is defined?
op<optional<T> is defined only if op<T is defined.
> If op< isn't defined (ie complex<> or, technically, pointers) do you
> still want std::less?

std::less<optional<T>> is defined only if std::less<T> id defined.
>
>>>>
>>>> 1 - op<(optional<T>, optional<T>) is "sensible" but somewhat arbitrary
>> I don't agree here. We don't need anything arbitrary.
>> op<optional<T>,optional<T>) must be defined only if op<(T,T> is defined.
> It is arbitrary in the sense of where "none" is ordered.
Agreed. we have decided that optional<T> is some way none_t+T and not
T+none_t.
>
> I (strongly!) agree with the only if op<(T,T> is defined.
> (And famously believe op>=(optional<T>,optional<T>) should be based on
> op>=(T,T), instead of !op<(T,T) )
Agree again.
>
>>>> 2 - op<(optional<T>, T) is questionable, often (usually?) wrong
>> Agreed.
>>>> 3 - in general, func(optional<T>, optional<T>) should work if passed
>>>> T's (ie implicit conversion is important)
>> I have my doubts here. Implicit conversions provide often (usually?)
>> unexpected behavior.
> I think we need a general guideline for the std library for when
> implicit is OK. ie Is it OK for dumb_ptr? string_view? etc.
> That's something I'd like to work on. I _think_ there is a general
> guideline, but maybe it is too case-by-case?
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).

Transitivity:
If we have types R, S, T such that R <: S <: T with implicit conversions
from R to S and from S to T, there should be also an implicit conversion
from R to T. That is R <: T. Note that C++ conversions are not transitive.

Identity: R ° S = identity
If we have types R, S such that R <: S
For any r:R R(S(r)) == r.

That is, there is no loss of information.

Efficiency
The cost of the implicit conversion from the subtype to the super type
is almost null. Conversions that implies a high conversion cost must be
explicit.

Refinement
The conversions from/to the super type must be defined on the sub-type
(this is in line with OO sub-typing, we can refine, but not generalize).
Defining implicit conversion on the super-type side would invalidate
valid programs. If we had

   class S
   void f(S);

and now we define a subtype R of S, R <: S, with an implicit conversion
from R to S.

   R r;
   f(r); // well formed

Now if we define a super type of T fo S, S <: T, that defines implicit
conversions from S to T and from R to S, and add a generalization for f

   void f(T);

The previous program would not be any more well formed

   R r;
f(r); // ambiguous conversion f(S) and f(T)

That is, super typing is not allowed. This point should be the most
controversial, but I think it is the most important :(

>
>>
>>>
>>>
>> 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?

Vicente


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