opIndex operators

bearophile bearophileHUGS at lycos.com
Sat Apr 13 03:48:37 PDT 2013


On Saturday, 13 April 2013 at 09:53:01 UTC, gedaiu wrote:
> Hi again!
>
> I don't understand why we have opIndex() and opIndexAssign()... 
> can anyone explain this for me?

opIndex returns the value contained in the "array", while 
opIndexAssign does the opposite, it puts in your "array" the 
given value. If you use opIndex and return the item by reference 
you sometimes don't need opIndexAssign. But for other cases you 
need both.

Info on D operator overloading:
http://dlang.org/operatoroverloading.html


> In D when I have this method
>
> Value& opIndex(Value index) {
> 	return container[index];
> }
>
> I get this error.
>
> Error: no identifier for declarator Value
> Error: semicolon expected, not '&'
> Declaration expected, not '&'

In D there isn't that & syntax. We have "ref". But it's not 
usable in all the situations where you use & in C++.


> And also, how you can implement custom structs that acts like a 
> multilevel array in D like in c++?

By multi-level array I think you mean something like a matrix:


import std.stdio;

struct Foo {
     float[] mat;
     size_t nCols;

     this(in size_t r, in size_t c) pure nothrow
     in { // pre-condition
         assert(r > 0);
         assert(c > 0);
     } body {
         nCols = c;
         mat.length = r * c; // All NaN.
     }

     float opIndex(in size_t r, in size_t c) pure nothrow {
         return mat[r * nCols + c];
     }

     float opIndexAssign(in float value, in size_t r, in size_t c)
     pure nothrow {
         mat[r * nCols + c] = value;
         return value;
     }
}

void main() {
     auto m = Foo(3, 5);
     m[1, 3] = 5.5;
     m[1, 3].writeln;
     m.mat.writeln;
}



An alternative design is to use ref. Here it can be used:


import std.stdio;

struct Foo {
     float[] mat;
     size_t nCols;

     this(in size_t r, in size_t c) pure nothrow
     in {
         assert(r > 0);
         assert(c > 0);
     } body {
         nCols = c;
         mat.length = r * c; // All NaN.
     }

     ref float opIndex(in size_t r, in size_t c) pure nothrow {
         return mat[r * nCols + c];
     }
}

void main() {
     auto m = Foo(3, 5);
     m[1, 3] = 5.5;
     m[1, 3].writeln;
     m.mat.writeln;
}


Bye,
bearophile


More information about the Digitalmars-d-learn mailing list