const references in C++ and D

bearophile bearophileHUGS at lycos.com
Sun May 30 16:03:57 PDT 2010


I am translating a small C++ program to D2 and I am having problems. I am learning, but my mind is not large enough for all the subtleties of both C++ and D2 yet :-)

This C++ program compiles:


struct Vec {
    void operator+(const Vec& other) {}
};
Vec bar(Vec x) {
    return x;
}
int main() {
    Vec() + bar(Vec());
}



I think this is the equivalent D2 program:

// program #1
struct Vec {
    void opBinary(string Op:"+")(const ref Vec other) {}
}
Vec bar(Vec x) {
    return x;
}
void main() {
    Vec() + bar(Vec()); // line 9
}


But DMD gives me:
temp3.d(9): Error: function temp3.Vec.opBinary!("+").opBinary (ref const const(Vec) other) is not callable using argument types (Vec)
temp3.d(9): Error: bar((Vec())) is not an lvalue


I vaguely remember a discussion about this in the D newsgroup, that D acts like this on purpose, so I think this is not a D bug. What is the right way to translate that C++ code to D2? (So far I have just commented out the 'ref' in opBinary).


Another case, to me it seems the same problem (D2 code):


// program #2
struct Vec {
    Vec opOpAssign(string Op:"+=")(ref Vec other) {
        return this;
    }
    Vec opBinary(string Op:"*")(int k) {
        return this;
    }
}
void main() {
    Vec x;
    x += Vec() * 2; // line 12
}


DMD prints:
temp3.d(12): Error: function temp3.Vec.opOpAssign!("+=").opOpAssign (ref Vec other) is not callable using argument types (Vec)
temp3.d(12): Error: (Vec()).opBinary(2) is not an lvalue

Again I have just commented out the 'ref' here and in most other operator overloading methods.


I have seen that in some cases I can use "auto ref" (like in those two examples), but not in all of them, I don't know why. For example here:


// program #3
struct Vec {
    Vec opOpAssign(string Op)(auto ref Vec other) if (Op == "+=") {
        return this;
    }
    Vec opBinary(string Op:"+")(Vec other) {
        Vec result;
        return result += other;
    }
}
void main() {
    Vec v;
    v += Vec() + Vec(); // line 13
}


DMD prints:
temp3.d(13): Error: function temp3.Vec.opOpAssign!("+=").opOpAssign (auto ref Vec other) is not callable using argument types (Vec)
temp3.d(13): Error: (Vec()).opBinary((Vec())) is not an lvalue

Do you know why "auto ref" isn't right here?

Bye and thank you,
bearophile


More information about the Digitalmars-d-learn mailing list