digitalmars.D - My story of C++ vs. D and trying to return classes by value
- Michael Coupland (53/53) May 19 2004 So I was porting my C++ vector code to D in preparation for my first big...
- Norbert Nemec (3/62) May 20 2004 You would probably want to use struct instead of class. A struct is alwa...
- Michael Coupland (20/22) May 20 2004 I thought about doing that, but I was a little hesitant because I
- Andy Friesen (8/21) May 20 2004 You can come close by defining a static opCall method that returns a
So I was porting my C++ vector code to D in preparation for my first big D project, and I ran into the following problem: I have overloaded * and *= scalar multiplication operations for the vector class, and I would prefer to write *= in terms of *. However, I tried copying my C++ code, which resulted in the following (broken) D code: // BROKEN class Vec2( ScalarType ) { // ... code ... //////////////////////////////////// // Overloaded * and *= Vec2 opMul( ScalarType s ) { return new Vec2( x*s, y*s ); } Vec2 opMulAssign( ScalarType s ) { this = this * s; return this; } } I tried compiling, and *= didn't seem to be working. In retrospect, it was a silly coding error: I'm overwriting the this pointer in opMulAssign(), which was resulting in some of that good ol' "undefined" behavior. As I was typing up a complaint/help request to this board, I realized that there was an interesting solution: do it the other way! So I wrote * in terms of *= and got the following (working) code: // WORKS! class Vec2( ScalarType ) { // ... code ... //////////////////////////////////// // Overloaded * and *= Vec2 opMul( ScalarType s ) { Vec2 res = new Vec2(this); res *= s; return res; } Vec2 opMulAssign( ScalarType s ) { x *= s; y *= s; return this; } } It just goes to show that you need to be careful when you're used to C++. I'm still trying to get my D-legs under me, and I figured that this might be a helpful story for others who are still beginning with D. Michael Coupland
May 19 2004
You would probably want to use struct instead of class. A struct is always handled by value. Michael Coupland wrote:So I was porting my C++ vector code to D in preparation for my first big D project, and I ran into the following problem: I have overloaded * and *= scalar multiplication operations for the vector class, and I would prefer to write *= in terms of *. However, I tried copying my C++ code, which resulted in the following (broken) D code: // BROKEN class Vec2( ScalarType ) { // ... code ... //////////////////////////////////// // Overloaded * and *= Vec2 opMul( ScalarType s ) { return new Vec2( x*s, y*s ); } Vec2 opMulAssign( ScalarType s ) { this = this * s; return this; } } I tried compiling, and *= didn't seem to be working. In retrospect, it was a silly coding error: I'm overwriting the this pointer in opMulAssign(), which was resulting in some of that good ol' "undefined" behavior. As I was typing up a complaint/help request to this board, I realized that there was an interesting solution: do it the other way! So I wrote * in terms of *= and got the following (working) code: // WORKS! class Vec2( ScalarType ) { // ... code ... //////////////////////////////////// // Overloaded * and *= Vec2 opMul( ScalarType s ) { Vec2 res = new Vec2(this); res *= s; return res; } Vec2 opMulAssign( ScalarType s ) { x *= s; y *= s; return this; } } It just goes to show that you need to be careful when you're used to C++. I'm still trying to get my D-legs under me, and I figured that this might be a helpful story for others who are still beginning with D. Michael Coupland
May 20 2004
Norbert Nemec wrote:You would probably want to use struct instead of class. A struct is always handled by value.I thought about doing that, but I was a little hesitant because I wouldn't be able to have: this( ScalarType s ) { x = s; y = s; } But in retrospect, using a struct is a 'more correct' choice (vectors are simple aggregates). I don't particularly use that constructor anyway, but I'd appreciate a suggestion on how to recreate the following (C++) typedef Vec2<float> Vec2f; Vec2f test_vec( 1, 2 ); I don't know how to do something like this without constructors similar to the one above. I know that /static/ structs can be initialized as: static Vec2f test_vec = { 1, 2 }; which would be fine for me, except that it doesn't work for non-static variables. Any suggestions? Michael Coupland
May 20 2004
Michael Coupland wrote:I'd appreciate a suggestion on how to recreate the following (C++) typedef Vec2<float> Vec2f; Vec2f test_vec( 1, 2 ); I don't know how to do something like this without constructors similar to the one above. I know that /static/ structs can be initialized as: static Vec2f test_vec = { 1, 2 }; which would be fine for me, except that it doesn't work for non-static variables. Any suggestions?You can come close by defining a static opCall method that returns a Vector to get this: Vector v = Vector(1,2,3); I think it's ugly and evil, but you could also make a nonstatic opCall that makes the vector mutate and return itself: Vector v; v(1,2,3); -- andy
May 20 2004