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.


Reply via email to