digitalmars.D.learn - Passing rvalues to functions expecting const ref
- Minas Mina (19/19) Dec 23 2012 Hi. In C++, I can do this:
- Namespace (4/4) Dec 23 2012 As long as you use structs this should work, as you can see here:
- Minas Mina (3/7) Dec 23 2012 Thank you. I had forgotten to supply the constructor to the
- John Chapman (3/7) Dec 23 2012 I don't think this will work after 2.061 is released. The
- Namespace (8/15) Dec 23 2012 I hope not. As long as "auto ref" don't work for normal
- Minas Mina (99/104) Dec 23 2012 struct Vector3
- Minas Mina (25/25) Dec 23 2012 There's another problem though:
Hi. In C++, I can do this:
struct Vector3
{
Vector3(_x, _y, _z); // constructor
};
float dot(const Vector3 &v, const Vector3 &u);
dot(Vector3(0, 0, 0), Vector3(1, 1, 1));
------------------------------------
In D, I can't -- and it's really annoying, because I am forced to
make a copy, i.e:
dot(Vector3 v, Vector3 u);
I don't want this.
The other solution is this:
Vector3 v = {0, 0, 0};
Vector3 u = {1, 1, 1};
dot(v,u); // dot(const ref Vector3 v, const ref Vector3 u);
But it's not as clean.
Why can't I do what I can in C++? Is it a technical or a design
decision? Are there plans to support it?
Dec 23 2012
As long as you use structs this should work, as you can see here: http://dpaste.dzfl.pl/03adf3d1 But if you use classes, it does not work anymore. So I like it a lot, that it works with structs. :)
Dec 23 2012
On Sunday, 23 December 2012 at 12:08:47 UTC, Namespace wrote:As long as you use structs this should work, as you can see here: http://dpaste.dzfl.pl/03adf3d1 But if you use classes, it does not work anymore. So I like it a lot, that it works with structs. :)Thank you. I had forgotten to supply the constructor to the struct :/
Dec 23 2012
On Sunday, 23 December 2012 at 12:08:47 UTC, Namespace wrote:As long as you use structs this should work, as you can see here: http://dpaste.dzfl.pl/03adf3d1 But if you use classes, it does not work anymore. So I like it a lot, that it works with structs. :)I don't think this will work after 2.061 is released. The behaviour is changing to disallow struct literals as lvalues.
Dec 23 2012
On Sunday, 23 December 2012 at 18:32:47 UTC, John Chapman wrote:On Sunday, 23 December 2012 at 12:08:47 UTC, Namespace wrote:I hope not. As long as "auto ref" don't work for normal functions, this change would be very inconvenient... Minas Mina: Show me the whole code, I think that your opBinary functions returns rvalues. This would be a good and important case for "auto ref". But until now it is only for template paramters...As long as you use structs this should work, as you can see here: http://dpaste.dzfl.pl/03adf3d1 But if you use classes, it does not work anymore. So I like it a lot, that it works with structs. :)I don't think this will work after 2.061 is released. The behaviour is changing to disallow struct literals as lvalues.
Dec 23 2012
On Sunday, 23 December 2012 at 20:40:09 UTC, Namespace wrote:Minas Mina: Show me the whole code, I think that your opBinary functions returns rvalues. This would be a good and important case for "auto ref". But until now it is only for template paramters...struct Vector3 { float x, y, z; this(float _x, float _y, float _z) { x = _x; y = _y; z = _z; } // negate operator Vector3 opUnary(string s)() const if( s == "-" ) { Vector3 temp = this; temp.x = -temp.x; temp.y = -temp.y; temp.z = -temp.z; return temp; } // + operator for completeness Vector3 opUnary(string s)() const if( s == "+" ) { return this; } // binary operators Vector3 opBinary(string op) (float val) const { static if( op == "+" ) { Vector3 temp = this; temp.x += val; temp.y += val; temp.z += val; } else static if( op == "-" ) { Vector3 temp = this; temp.x -= val; temp.y -= val; temp.z -= val; } else static if( op == "*" ) { Vector3 temp = this; temp.x *= val; temp.y *= val; temp.z *= val; } else static if( op == "/" ) { Vector3 temp = this; temp.x /= val; temp.y /= val; temp.z /= val; } return temp; } Vector3 opBinary(string op) (Vector3 v) const { static if( op == "+" ) { Vector3 temp = this; temp.x += v.x; temp.y += v.y; temp.z += v.z; } static if( op == "-" ) { Vector3 temp = this; temp.x -= v.x; temp.y -= v.y; temp.z -= v.z; } static if( op == "*" ) { Vector3 temp = this; temp.x *= v.x; temp.y *= v.y; temp.z *= v.z; } return temp; } } /// dot product of two Vector3 vectors safe pure float dot(Vector3 u, Vector3 v) { return u.x * v.x + u.y * v.y + u.z * v.z; } dot is making copies now because what I have shown earlier does not work... It's what I'm using now.
Dec 23 2012
There's another problem though:
struct Vector3
{
float x, y, z;
this(float _x, float _y, float _z)
{
x = _x;
y = _y;
z = _z;
}
// the binary +, - operators are defined
}
Vector3 cross(const ref Vector3 a, const ref Vector3 b);
...
Vector3 n = cross(b-a, c-a);
raytracing/triangle.d(58): Error: function
raytracing.vector.cross (ref const(Vector3) a, ref const(Vector3)
b) is not callable using argument types (Vector3,Vector3)
raytracing/triangle.d(58): Error: this.b.opBinary(this.a) is not
an lvalue
raytracing/triangle.d(58): Error: this.c.opBinary(this.a) is not
an lvalue
That's what I actually want.
Dec 23 2012









"Minas Mina" <minas_mina1990 hotmail.co.uk> 