www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - opIndex overload for slice not working...

reply Enjoys Math <enjoysmath gmail.com> writes:
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
Jan 24
next sibling parent biozic <dransic gmail.com> writes:
On Monday, 25 January 2016 at 06:37:13 UTC, 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
You're mixing slicing and indexing. Use *opSlice* to support i..j slicing notation. --- import std.stdio; class V(T) { public: this() {} V opIndex(size_t i, size_t j) { writeln("Indexing"); return this; } V opSlice(size_t i, size_t j) { writeln("Slicing"); return this; } } void main() { auto v = new V!int(); auto w = v[3, 4]; // Indexing auto u = v[3..4]; // Slicing } ---
Jan 24
prev sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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
Jan 24