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

Reply via email to