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








Andy Friesen <andy ikagames.com>