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