Hello bearophile,
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.
Yes, by design, you can't have a reference to a temporary value.
What is the
right way to translate that C++ code to D2? (So far I have just
commented out the 'ref' in opBinary).
Thats' what I'd do.
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
--
... <IXOYE><