On Thu, Sep 04, 2014 at 09:04:33PM +0000, monarch_dodra via Digitalmars-d-learn wrote: > On Thursday, 4 September 2014 at 19:12:27 UTC, Ali Çehreli wrote: > >The documentation says "To overload a[], simply define opIndex with > >no parameters": > > > > http://dlang.org/operatoroverloading.html#Slice > > > >And it works with some uses of a[]. However, opSlice() seems to be > >needed to actually use the returned slice further. > > This must be new, as I've read that page several times, and have never > seen that before. Furthermore, I've done a *lot* pulls to improve > ranges' slicing capabilities, and no reviewer has ever mentioned this > before.
I'm the one responsible for this. It's based on Kenji's PR that implements multidimensional slicing; in his design, he specifically relegates opSlice to returning index range proxy objects, so that mixed single-indexing and range-indexing (i.e., expressions of the form A[1, 2..3, 4, 5..6]) will be easily implementable. Under this design, x..y is translated into A.opSlice(x,y), and the actual indexing with [] is translated into A.opIndex(...), so in this case it becomes: A.opIndex(1, A.opSlice(2,3), 4, A.opSlice(5,6)); The idea, really, is that by this unification we can write a generic opIndex that handles any combination of single indices and index ranges: struct Array { ProxyObj opSlice(int i, int j) { ... } void opIndex(A...)(A args) { foreach (arg; args) { static if (is(typeof(arg) == ProxyObj)) { // implement index range here } else if (is(typeof(arg) : size_t)) { // implement single index lookup // here } } } } By extension, therefore, it follows that implementing slice operations of the form A[] simply involves invoking A.opIndex() with no arguments. Of course, to maintain backward compatibility, Kenji's PR left the old semantics of opSlice intact, if no suitable implementation of opIndex is found for expressions of the form A[]. So this is what I documented on that page. T -- Question authority. Don't ask why, just do it.