Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
February 16, 2014 Can opCmp return a 'long' instead of 'int'? | ||||
---|---|---|---|---|
| ||||
Hello, The call signature for opCmp in a struct is: struct S { int opCmp(ref const S s) const { ... } } int opCmp(ref const S s) const { return _val - s._val; } This works fine if _val is 'int'. However, if _val is 'long' then subtracting 2 longs may not result in an int - and therefore I would have to replace the subtraction above with 2 comparison operators. My question is: Can I rewrite opCmp to return a 'long', like: struct S { long opCmp(ref const S s) const { return _val - s.val; } } This does compile and run correctly, but are there any hidden assumptions or requirements on the return value of opCmp that I should be aware of? Is there any reason that doing this may be not be wise? Thanks, Saurabh |
February 16, 2014 Re: Can opCmp return a 'long' instead of 'int'? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Saurabh Das | On 02/16/2014 02:59 PM, Saurabh Das wrote:
>
> This does compile and run correctly, but are there any hidden
> assumptions or requirements on the return value of opCmp that I should
> be aware of? Is there any reason that doing this may be not be wise?
No, this is fine.
|
February 16, 2014 Re: Can opCmp return a 'long' instead of 'int'? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 02/16/2014 04:13 PM, Timon Gehr wrote:
> On 02/16/2014 02:59 PM, Saurabh Das wrote:
>>
>> This does compile and run correctly, but are there any hidden
>> assumptions or requirements on the return value of opCmp that I should
>> be aware of? Is there any reason that doing this may be not be wise?
>
> No, this is fine.
To be more precise: Returning long is fine.
The subtraction trick does not work in general regardless of return type:
import std.stdio;
struct S{
int d;
int opCmp(S r){ return d - r.d; }
}
void main(){
assert(S(1)<S(2)); // passes. ok.
assert(S(int.min)>S(int.max)); // passes. oops.
}
|
February 16, 2014 Re: Can opCmp return a 'long' instead of 'int'? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | Timon Gehr:
> assert(S(1)<S(2)); // passes. ok.
> assert(S(int.min)>S(int.max)); // passes. oops.
A possible solution is to add to Phobos (unless it's already there) a variadic templated funcion cmpBuilder() that accepts an even number of arguments, that are seen as pairs. Usage example:
struct Foo {
int x, y;
string s;
int opCmp(in ref Foo r) {
return cmpBuilder(x, r.x, y.abs, r.y.abs, s, r.s);
}
}
Is this worth adding to Phobos?
Bye,
bearophile
|
February 16, 2014 Re: Can opCmp return a 'long' instead of 'int'? | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 02/16/2014 04:40 PM, bearophile wrote:
> Timon Gehr:
>
>> assert(S(1)<S(2)); // passes. ok.
>> assert(S(int.min)>S(int.max)); // passes. oops.
>
> A possible solution is to add to Phobos (unless it's already there) a
> variadic templated funcion cmpBuilder() that accepts an even number of
> arguments, that are seen as pairs. Usage example:
>
> struct Foo {
> int x, y;
> string s;
> int opCmp(in ref Foo r) {
> return cmpBuilder(x, r.x, y.abs, r.y.abs, s, r.s);
> }
> }
>
> Is this worth adding to Phobos?
>
> Bye,
> bearophile
IMO no (lots of repetition), but forwarding opCmp is:
struct Foo{
int x,y;
string s;
private @property order(){ return tuple(x, abs(y), s); }
mixin OrderBy!order;
}
Furthermore, the language should be updated such that the built-in types are not special w.r.t. operators. Eg:
1.opBinary!"+"(2)
1.opCmp(2)
should work.
The following should be supported as well:
struct Foo{
int x,y;
string s;
mixin OrderBy!(()=>tuple(x, abs(y), s));
}
(Currently DMD bans function literals as members.)
|
February 17, 2014 Re: Can opCmp return a 'long' instead of 'int'? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Sunday, 16 February 2014 at 15:19:08 UTC, Timon Gehr wrote:
> On 02/16/2014 04:13 PM, Timon Gehr wrote:
>> On 02/16/2014 02:59 PM, Saurabh Das wrote:
>>>
>>> This does compile and run correctly, but are there any hidden
>>> assumptions or requirements on the return value of opCmp that I should
>>> be aware of? Is there any reason that doing this may be not be wise?
>>
>> No, this is fine.
>
> To be more precise: Returning long is fine.
>
> The subtraction trick does not work in general regardless of return type:
>
> import std.stdio;
> struct S{
> int d;
> int opCmp(S r){ return d - r.d; }
> }
>
> void main(){
> assert(S(1)<S(2)); // passes. ok.
> assert(S(int.min)>S(int.max)); // passes. oops.
> }
Right. I didn't expect that! So I shouldn't use it anyway. Thanks!
Saurabh
|
Copyright © 1999-2021 by the D Language Foundation