Semantics of postfix ops for classes

Andrej Mitrovic andrej.mitrovich at gmail.com
Fri Jul 20 08:12:45 PDT 2012


According to TDPL postfix operators are rewritten to call prefix
operators, e.g. on this call for some user-type object named a:

auto b = a++;

// is converted to:
auto b = ((ref x) { auto t = x; ++x; return t; })(a);

But I don't see how this is reasonable for classes. Examine:

struct Struct {
    int x = 1;
    Struct opUnary(string op : "++")() {
        x++;
        return this;
    }
}

class Class {
    int x = 1;
    Class opUnary(string op : "++")() {
        x++;
        return this;
    }
}

void main()
{
    Struct foo1;
    Struct foo2 = foo1++;
    assert(foo1.x != foo2.x);  // ok

    Class bar1 = new Class;
    Class bar2 = bar1++;
    assert(bar1.x != bar2.x);  // fail
}

It's clear why, the rewrite that calls "auto t = x" simply binds
another reference to the same object.

Unfortunately this makes it hard to wrap C++ libraries which have both
prefix/postfix operators defined. Currently I wrap these in e.g.
"preInc"/"postInc" methods and I explicitly disable the prefix/postfix
opUnary methods.

Are the semantics of this rewrite ok with people who use op overloads?
I found them to be surprising, but then again I don't use op overloads
that much, I'm just noticing the difference between C++ and D.


More information about the Digitalmars-d mailing list