$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] [Review:Algorithms] Order of args to clamp
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2011-09-26 17:03:40
Le 26/09/11 20:01, Stewart, Robert a écrit :
> Vicente J. Botet Escriba wrote:
>> Le 26/09/11 13:36, Dave Abrahams a écrit :
>>> Note: you can solve that problem by asking the caller to do
>>> the conversion ;-)
>>>
>> I'm not sure this could always be the desired interface for
>> the caller. When I want to clip an 22 bit integer to a 16 bit
>> integer, I expect the result be a 16 bit integer. So in these
>> cases the result type will be the types of lo and hi.
>>
>> int v;
>> short lo,hi;
>> short res= clamp(v, lo,hi);
> How does the algorithm select the smaller return type when clamping to a limit, while selecting the larger return type otherwise?
Well, maybe clamp shouldn't return the clamp-ed's type, but the bound's
type. We could see the clamp function as a conversion limiting the valid
values.
>
>> And in this case I can not convert the 22 bits integer to a 16
>> bit because I would lost some essential information.
>>
>> short res= clamp(short(v), lo,hi); // not the expected
>> // behavior
> That's the caller's fault, of course.
I agree.
>
>> That means that I will need to convert to the
>>
>> short res= short(clamp(v, int(lo),int(hi)));
> Right, but all of the information is visible to the caller.
>
> You could also do that like this:
>
> clamp<int>(v, lo, hi)
This force the bound type to be implicitly convertible to the clamp-ed
type and the clamped type to be implicitly convertible to the result type.
short res =clamp<int>(v,lo,hi);
>
> For comparison with v, lo and hi must be promoted anyway, so the three-type version doesn't help. Forcing the caller to disambiguate isn't so bad, at least in this case.
>
An other possibility is to pass of the return type as template parameter:
short res = clamp<short>(v,lo,hi);
Note that in this particular case the single conversion is done when
lo<v<hi and in this case it is safe as in the range.
The interface with 3 types could be
template <typename Res, typename T, typename Lo, Typename Hi>
Res clamp(const &T, const &Lo, const &Hi);
The constraint here would be that T, Hi, and Lo are explicitly
convertible to Res.
Vicente