August 07, 2013
import std.stdio;

struct ArrayTypeA {
        int[12] data;
        size_t length() { return 12; }
        auto opSlice(size_t s, size_t e) { return data[s .. e]; }
}

struct ArrayTypeB {
        int[24] data;

        auto opSlice(size_t s, size_t e) { return data[s..  e]; }
        size_t length() { return 24; }
}

struct Array
{
        union {
                ArrayTypeA a = ArrayTypeA.init;
                ArrayTypeB b;
        }
        bool isA = true;
        auto opDispatch(string s, T...)(T args)
        {
                if(isA)
                        return __traits(getMember, a, s)(args);
                else
                        return __traits(getMember, b, s)(args);
        }
}

void main() {

        Array ar;
        writeln(ar.length); // compiles

         writeln(ar[3 .. 5]); // does not
        // /tmp/test.d(37): Error: Array cannot be sliced with []
}

I'd say, if something rewrites to MyType.opSlice than it's a case for opDispatch, too.
August 07, 2013
On Wednesday, 7 August 2013 at 21:08:24 UTC, Tobias Pankrath wrote:
> import std.stdio;
>
> struct ArrayTypeA {
>         int[12] data;
>         size_t length() { return 12; }
>         auto opSlice(size_t s, size_t e) { return data[s .. e]; }
> }
>
> struct ArrayTypeB {
>         int[24] data;
>
>         auto opSlice(size_t s, size_t e) { return data[s..  e]; }
>         size_t length() { return 24; }
> }
>
> struct Array
> {
>         union {
>                 ArrayTypeA a = ArrayTypeA.init;
>                 ArrayTypeB b;
>         }
>         bool isA = true;
>         auto opDispatch(string s, T...)(T args)
>         {
>                 if(isA)
>                         return __traits(getMember, a, s)(args);
>                 else
>                         return __traits(getMember, b, s)(args);
>         }
> }
>
> void main() {
>
>         Array ar;
>         writeln(ar.length); // compiles
>
>          writeln(ar[3 .. 5]); // does not
>         // /tmp/test.d(37): Error: Array cannot be sliced with []
> }
>
> I'd say, if something rewrites to MyType.opSlice than it's a case for opDispatch, too.

I wish it did too, but apparently there is a reason why not. I can't remember what I was told off the top of my head, but I remember not being 100% convinced.

It would greatly simplify writing some wrapper types.