overload binary + operator to work with different types
Simen Kjærås
simen.kjaras at gmail.com
Tue Mar 13 19:28:12 UTC 2018
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
More information about the Digitalmars-d-learn
mailing list