Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
March 13, 2018 overload binary + operator to work with different types | ||||
---|---|---|---|---|
| ||||
I want to basically make this work: >auto l = new List(); >l += 5; I managed to do this: >class List >{ > int[] items; > ref List opBinary(string op)(int rhs) if(op == "+") > { > items ~= rhs; > return *this; > } } Note the ref in the fucntion return, I also want to return a reference to the class so that this Works: > l += 5 + 8 + 9 ... ; Could someone point out how do that/what's wrong with my attempy? |
March 13, 2018 Re: overload binary + operator to work with different types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc | On Tuesday, March 13, 2018 18:55:35 Marc via Digitalmars-d-learn wrote: > I want to basically make this work: > >auto l = new List(); > >l += 5; > > I managed to do this: > >class List > >{ > > > > int[] items; > > ref List opBinary(string op)(int rhs) if(op == "+") > > { > > > > items ~= rhs; > > return *this; > > > > } > > } > > Note the ref in the fucntion return, I also want to return a > > reference to the class so that this Works: > > l += 5 + 8 + 9 ... ; > > Could someone point out how do that/what's wrong with my attempy? + is overloaded with opBinary, and += is overloaded using opOpAssign: https://dlang.org/spec/operatoroverloading.html#op-assign http://ddili.org/ders/d.en/operator_overloading.html - Jonathan M Davis |
March 13, 2018 Re: overload binary + operator to work with different types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Tuesday, 13 March 2018 at 19:05:00 UTC, Jonathan M Davis wrote: > On Tuesday, March 13, 2018 18:55:35 Marc via Digitalmars-d-learn wrote: >> I want to basically make this work: >> >[...] >> >> I managed to do this: >> > [...] >> >> } >> >> Note the ref in the fucntion return, I also want to return a >> >> reference to the class so that this Works: >> > [...] >> >> Could someone point out how do that/what's wrong with my attempy? > > + is overloaded with opBinary, and += is overloaded using opOpAssign: > > https://dlang.org/spec/operatoroverloading.html#op-assign http://ddili.org/ders/d.en/operator_overloading.html > > - Jonathan M Davis Soon as I posted I found out opOpAssign. I've had got close than I thought: > List opOpAssign(string op)(int rhs) if(op == "+") > { > items ~= rhs; > return this; > } Thanks! |
March 13, 2018 Re: overload binary + operator to work with different types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marc | On Tuesday, 13 March 2018 at 18:55:35 UTC, Marc wrote:
> I want to basically make this work:
>
>>auto l = new List();
>>l += 5;
>
> I managed to do this:
>
>>class List
>>{
>> int[] items;
>> ref List opBinary(string op)(int rhs) if(op == "+")
>> {
>> items ~= rhs;
>> return *this;
>> }
> }
>
> Note the ref in the fucntion return, I also want to return a reference to the class so that this Works:
>
>> l += 5 + 8 + 9 ... ;
>
> Could someone point out how do that/what's wrong with my attempy?
First, D has a concatenation operator (~). Use it instead of + if concatenation is what you want.
Now, to your question: classes are reference types in D, so you don't need a 'ref' on function:
List opBinary(string op : "~")(int rhs) {
items ~= rhs;
return this;
}
This will return the exact same List that you've just appended to. However, that won't do what you're asking, since you specifically asked for += (which I will interpret as ~=, for reasons explained above). When the operation you want to overload is an assignment operator, as in +=, -=, ~=, etc, you'll need to write a function called opOpAssign:
List opOpAssign(string op : "~")(int rhs) {
items ~= rhs;
return this;
}
With opOpAssign, this code will work:
unittest {
List a = new List();
a ~= 1;
a ~= 2;
a ~= 3;
}
However, we still haven't gotten code on the format 'a ~= 1 ~ 2 ~ 3;' to work, and that's because we can't. When you have an assignment expression (something that looks like 'lhs = rhs'), the left-hand side is evaluated separately from the right-hand side, and then the assignment is performed. Since '1 ~ 2 ~ 3' doesn't do what you want it to, neither will 'a ~= 1 ~ 2 ~ 3', since it's essentially '(a) = (1 ~ 2 ~ 3);'.
Overloading just opBinary though (as in my first example), we can make this work: 'a ~ 1 ~ 2 ~ 3;'. The problem, as you probably notice, is that there's no assignment there. It looks as though you're just concatenating a bunch of items, and then discarding the result.
Now, since we've established that there's no way to do exactly what you want, maybe it's time to take a look at what you actually want. :p Why do you want to write that code? Why would a.append(1, 2, 3); not be good enough?
And given that seasoned D veterans know that the lhs and rhs of an assignment are evaluated separately, and that 'a ~ b' generally doesn't have side effects, you should think very carefully through your reasoning for breaking that intuition.
--
Simen
|
March 13, 2018 Re: overload binary + operator to work with different types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjærås | On 3/13/18 3:28 PM, Simen Kjærås wrote: > Now, since we've established that there's no way to do exactly what you want, maybe it's time to take a look at what you actually want. :p Why do you want to write that code? Why would a.append(1, 2, 3); not be good enough? Typically, we can do this with arrays quite easily, especially strings: arr ~= [1, 2, 3]; str ~= "123"; It would be nice to have another way to do this. a.append(1, 2, 3) would work , and you can do it in a nice variadic way with: append(T[] vals...) And this won't allocate anything on the heap (this is essentially how I did it in dcollections, see https://github.com/schveiguy/dcollections/blob/master/dcollections/model/Addable.d#L55). But most D containers, you would expect to be able to append a range. This is what I would recommend. It will work for arrays as well. -Steve |
Copyright © 1999-2021 by the D Language Foundation