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