user defined implicit casts

Reiner Pope some at address.com
Tue Jul 31 15:25:10 PDT 2007


Jarrett Billingsley wrote:
> Can you generalize that to a List!(any integer type)?  

Not quite, but that's D's fault. The following very nearly works, 
though, but it doesn't have a specialization on T. If it did, IFTI would 
break (which, as far as I see, is D's fault, and not something fundamental).

List!(T) opAdd(T)(List!(T) a, List!(T) b)
{
     ...
}

But anyway, the same problem holds if you want to write a templated 
accumulate function. The problem is in template specialization, not in 
the global operator overloading.

> What if (I know the 
> chances are slim but bear with me) you created a class derived from List 
> which wanted to change the behavior of opAdd?  

I hadn't thought of this situation. But I don't see anything wrong with 
the most obvious solution: if a class C has an operator overloaded, for 
instance opAdd, then only the members are considered in overloading for 
C.opAdd. If not, then consider globals.

I think this situation is very similar to the pseudo-member syntax that 
many people (including me) are keen on, to generalize the implicit 
properties for arrays to all types. The same problem arises there, and I 
would suggest the same solution.

> And is there anything that 
> you absolutely cannot do with member operator overloads, or problems which 
> static/global operator overloads solve more elegantly than member operator 
> overloads? 
> 

I think the example I gave is one such. Supposing that there is a way to 
generalise my example to any iteratable list of any numeric type, then I 
would say that making it a global is the best design. It makes the 
algorithm composable, independent of the underlying type (like STL). The 
alternative is to write:

template OpAddImpl(T, ThisType)
{
     static if (IsAddable!(T))
     {
         ThisType opAdd(ThisType other)
         {
             ...
         }
     }
}

class List(T)
{
     ...
     mixin OpAddImpl!(T, typeof(this));
}

class Vector(T)
{
     ...
     mixin OpAddImpl!(T, typeof(this));
}

// and the same for all the other list-looking classes

You could also try to use inheritance, but then you lose information 
about the return type, and it's also not currently possible with 
interfaces since they don't allow implementing even final member functions.

   -- Reiner



More information about the Digitalmars-d mailing list