digitalmars.D - reference return values
- Frank Fischer (25/25) May 08 2004 Hi,
- J Anderson (43/68) May 08 2004 You can use more then one [][] using a proxy object: This is something
- Frank Fischer (7/10) May 08 2004 Well, but that's not more than a workaround. The problem now is what to ...
- hellcatv hotmail.com (2/15) May 08 2004
- Mike Wynn (61/74) May 08 2004 some time ago I posted this example
- J Anderson (11/28) May 09 2004 Using the way I suggested is quite powerful because you can control each...
- Frank Fischer (15/31) May 09 2004 This could be usefull for arrays, but I don't talk about arrays. I mean
- Juan C (4/7) May 08 2004
- Frank Fischer (3/10) May 09 2004 No, m(1,1) should be an access to a member-field of M, not the creation
Hi, is there any way in D to return references to values (e.g. member variables of an object), like this in C++: class Matrix { private: double* data; public: .. double& at(int i, int j) { return data[i + j*rows]; } .. double& operator()(int i, int j) { return at(i,j); } } Thin one can use this class like this as lvalue: Matrix m(10,10); m.at(1,1) = 1.0; /* or with operators: */ m(1,1) = 1.0; One can see the two problems here: you need reference return values (or some equivalent syntax sugar) to use functions with more than zero parameters as lvalues (properties only work without parameters). For this special problem it would perhaps be possible to overload the array [] operator, but this can only be done with one single operator (that's the reason for using the call operator () in C++). I want to port some of my matrix-classes to D, and therefore something like this would be nice.
May 08 2004
Frank Fischer wrote:Hi, is there any way in D to return references to values (e.g. member variables of an object), like this in C++: class Matrix { private: double* data; public: .. double& at(int i, int j) { return data[i + j*rows]; } .. double& operator()(int i, int j) { return at(i,j); } } Thin one can use this class like this as lvalue: Matrix m(10,10); m.at(1,1) = 1.0; /* or with operators: */ m(1,1) = 1.0; One can see the two problems here: you need reference return values (or some equivalent syntax sugar) to use functions with more than zero parameters as lvalues (properties only work without parameters). For this special problem it would perhaps be possible to overload the array [] operator, but this can only be done with one single operator (that's the reason for using the call operator () in C++). I want to port some of my matrix-classes to D, and therefore something like this would be nice.You can use more then one [][] using a proxy object: This is something I posted before. You'll need to work it into your own problem. Most of the overhead would be optimised away. struct Col { private int [][] array; private int i; static Col opCall(int [][]array, int pos) { Col col; col.array = array; col.i = pos; return col; } int opIndex(int j) { return array[i][j]; } int opIndex(int j, int value) { return array[i][j] = value; } void length(int len) { array.length = len; } } class Array { private int [][] array; this(int size, int size2) { array.length = size; foreach ( inout int [] arr; array) arr.length = size2; } Col opIndex(int i) { return Col(array, i); } } int main (char[][] args) { Array a = new Array(10,10); a[1][0] = 5; a[1][1] = 6; printf("a[1][0] = %d\n", a[1][0]); printf("a[1][1] = %d\n", a[1][1]); return 0; } -- -Anderson: http://badmama.com.au/~anderson/
May 08 2004
In article <c7is2l$1arh$1 digitaldaemon.com>, J Anderson says...You can use more then one [][] using a proxy object: This is something I posted before. You'll need to work it into your own problem. Most of the overhead would be optimised away.Well, but that's not more than a workaround. The problem now is what to do, if i need both, a two-parameter operator (for matrix-like access) _and_ a one-parameter operator (for vector-like access) in one class? I cannot use the []-operator for both. And _most_ of the overhead is not _all_, and that's sth I don't like, because speed is an important factor in my case. Furthermore, i think "m(1,2)" or "m[1,2]" looks nicer than "m[1][2]" ;)
May 08 2004
can you overload opCall for this (if it's a struct at least) In article <c7jaoc$21nt$1 digitaldaemon.com>, Frank Fischer says...In article <c7is2l$1arh$1 digitaldaemon.com>, J Anderson says...You can use more then one [][] using a proxy object: This is something I posted before. You'll need to work it into your own problem. Most of the overhead would be optimised away.Well, but that's not more than a workaround. The problem now is what to do, if i need both, a two-parameter operator (for matrix-like access) _and_ a one-parameter operator (for vector-like access) in one class? I cannot use the []-operator for both. And _most_ of the overhead is not _all_, and that's sth I don't like, because speed is an important factor in my case. Furthermore, i think "m(1,2)" or "m[1,2]" looks nicer than "m[1][2]" ;)
May 08 2004
On Sat, 8 May 2004 19:00:28 +0000 (UTC), Frank Fischer <Frank_member pathlink.com> wrote:In article <c7is2l$1arh$1 digitaldaemon.com>, J Anderson says...some time ago I posted this example opCall return an int * so b[y][x] = v => *b(x, y) = v; so v = b[y][x] = => v = *b(x, y); ---------------------- import std.c.stdio; class B { int[] data; int lw; this( int xw, int yw ) { lw = xw; data=new int[xw*yw]; } int[] opCall( int y ) { return this[y]; } int * opCall( int x, int y ) { return &data[(y*lw)+x]; } int[] opIndex( int y ) { return data[(y*lw)..((y*lw)+lw)]; } void dump() { printf( "data [" ); foreach( int v; data ) { printf( "%d, ", v ); } printf( "]\n" ); } } int main( char[][] argv ) { B b = new B( 2, 2 ); int[] ar = b[0]; printf("ar.length:%d\n", ar.length); ar[0] = 1; ar[1] = 2; *(b(1,1)) =3; *(b(0,1)) =-4; b.dump(); return 1; } ------------------------ I though about having opCall return a struct that overloaded opCatAssign as there is no overloaded opAssign (that I've found) thus struct Element { int * ptr; Element opCatAssign( int i ) { *ptr = i; return *this; } int value() { return *ptr; } } class B { ... as about except .... Element opCall( int x, int y ) { Element rv; rv.ptr = &data[(y*lw)+x]; return rv; } } int main( char[][] argv ) { B b = new B( 2, 2 ); int[] ar = b[0]; printf("ar.length:%d\n", ar.length); ar[0] = 1; ar[1] = 2; b(1,1) ~= 3; b(0,1) ~= -4; b.dump(); return 1; } more overhead for little improvement, still think D needs true Mike.You can use more then one [][] using a proxy object: This is something I posted before. You'll need to work it into your own problem. Most of the overhead would be optimised away.Well, but that's not more than a workaround. The problem now is what to do, if i need both, a two-parameter operator (for matrix-like access) _and_ a one-parameter operator (for vector-like access) in one class? I cannot use the []-operator for both. And _most_ of the overhead is not _all_, and that's sth I don't like, because speed is an important factor in my case. Furthermore, i think "m(1,2)" or "m[1,2]" looks nicer than "m[1][2]" ;)
May 08 2004
Frank Fischer wrote:In article <c7is2l$1arh$1 digitaldaemon.com>, J Anderson says...It's the way you'd do it in C++ as well.You can use more then one [][] using a proxy object: This is something I posted before. You'll need to work it into your own problem. Most of the overhead would be optimised away.Well, but that's not more than a workaround.The problem now is what to do, if i need both, a two-parameter operator (for matrix-like access) _and_ a one-parameter operator (for vector-like access) in one class? I cannot use the []-operator for both. And _most_ of the overhead is not _all_, and that's sth I don't like, because speed is an important factor in my case. Furthermore, i think "m(1,2)" or "m[1,2]" looks nicer than "m[1][2]" ;)Using the way I suggested is quite powerful because you can control each dimension of the array ie: A[x].length = 10; A[x][y].length = 10; Also if you want to use the array for more then one thing, simply create a new class to do it and then call it by method using something like this: A.reverse[x][y] ... -- -Anderson: http://badmama.com.au/~anderson/
May 09 2004
On 2004-05-09, J Anderson <REMOVEanderson badmama.com.au> wrote:This could be usefull for arrays, but I don't talk about arrays. I mean matrices in the mathematical sense. So there's no need for controlling each dimension of subarrays. And I think it's strange to access elements of a matrix like this: A.matrix[i][j] A.vector[i] ... Wouldn't it be nicer to do it that way: A(i,j) and A(i) Of course, returning pointers could be a way out (as mentioned in another posting by someone), but I think that's not the way someone using this matrix-class would expect. And as always, something unexpected is a potential source of trouble.The problem now is what to do, if i need both, a two-parameter operator (for matrix-like access) _and_ a one-parameter operator (for vector-like access) in one class? I cannot use the []-operator for both. And _most_ of the overhead is not _all_, and that's sth I don't like, because speed is an important factor in my case. Furthermore, i think "m(1,2)" or "m[1,2]" looks nicer than "m[1][2]" ;)Using the way I suggested is quite powerful because you can control each dimension of the array ie: A[x].length = 10; A[x][y].length = 10; Also if you want to use the array for more then one thing, simply create a new class to do it and then call it by method using something like this: A.reverse[x][y] ...
May 09 2004
<snip>m.at(1,1) = 1.0; /* or with operators: */ m(1,1) = 1.0;</snip> M m = new M(1.0); would be clearer, no?
May 08 2004
On 2004-05-09, Juan C <Juan_member pathlink.com> wrote:<snip>No, m(1,1) should be an access to a member-field of M, not the creation of a new object.m.at(1,1) = 1.0; /* or with operators: */ m(1,1) = 1.0;</snip> M m = new M(1.0); would be clearer, no?
May 09 2004