www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Why does opDispatch not forward to operators?

reply "Tobias Pankrath" <tobias pankrath.net> writes:
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.
Aug 07 2013
parent "John Colvin" <john.loughran.colvin gmail.com> writes:
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.
Aug 07 2013