opIndex overload for slice not working...

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Jan 24 23:14:32 PST 2016


On 01/24/2016 10:37 PM, Enjoys Math wrote:
 > class V(T) {
 > public:
 >     this() {}
 >     V opIndex(size_t i, size_t j) {
 >       writeln("Hello, foo!");
 >       return this;
 >     }
 > }
 >
 > main() {
 >     auto v = new V!int();
 >     auto u = v[3..4];        // ERROR
 > }
 >
 > Error:
 > no [] operator overload for type the_module.V!int

That usage used to be supported by opSlice. Here is my interpretation of it:

 
http://ddili.org/ders/d.en/operator_overloading.html#ix_operator_overloading.opSlice

However, with relatively recent changes to D, expressions like v[3..4] 
are now represented more powerfully by opIndex() templates. Expressions 
3..4 must first be passed through an opSlice() template to describe what 
it means to your type.

Usually, 3..4 can trivially be represented by a Tuple!(size_t, size_t) 
(or by a custom type):

    struct Range {
        size_t begin;
        size_t end;
    }

    Range opSlice(size_t dimension)(size_t begin, size_t end) {
        return Range(begin, end);
    }

My interpretation of this new scheme is at

 
http://ddili.org/ders/d.en/templates_more.html#ix_templates_more.multi-dimensional%20operator%20overloading

Here is your code with those changes:

import std.stdio;

class V(T) {
public:
    this() {}

    struct Range {
        size_t begin;
        size_t end;
    }

    // Could return a Tuple
    Range opSlice(size_t dimension)(size_t begin, size_t end) {
        return Range(begin, end);
    }

    V opIndex(A...)(A args) {
        foreach (dimension, arg; args) {
            writefln("dimension: %s, accessing %s", dimension, arg);
        }
        return this;
    }
}

void main() {
    auto v = new V!int();
    auto u = v[3..4];
}

Prints

dimension: 0, accessing Range(3, 4)

Ali



More information about the Digitalmars-d-learn mailing list