Cumbersome overloading of mixed-in functions

Jarrett Billingsley kb3ctd2 at yahoo.com
Sat Aug 19 15:55:15 PDT 2006


Say I want to add a bunch of (virtual) methods to a class.  All these 
methods do very similar things, just on different types.  Hmm, sounds like a 
job for a template.

So I write up a templated version of the method:

template FuncTemplate(T)
{
    void func(T val)
    {
        // do some stuff with val
    }
}

Now I can mix it into the class.  I have, no joke, about 10 or 15 types I 
want to mix this in as.  So I do this:

class Foo
{
    mixin FuncTemplate!(int);
    mixin FuncTemplate!(float);
}

Oh crap, I can't even go any further right now.  If I try to instantiate the 
class and call these methods:

Foo f = new Foo();
f.func(5);

I get the error:

function blah.Foo.FuncTemplate!(int).func conflicts with 
blah.Foo.FuncTemplate!(float).func at..

I look up in the spec, and find that it's possible to overload these 
functions, but it has to be done manually, using dummy mixin names and then 
aliasing them:

class Foo
{
    mixin FuncTemplate!(int) intFunc;
    mixin FuncTemplate!(float) floatFunc;

    alias intFunc.func func;
    alias floatFunc.func func;
}

Foo f = new Foo();
f.func(5); // yay, works

Now for the other 12 or 13 types, which means lots of namespace pollution in 
my class for all the dummy mixin names, and a matching alias for each mixin. 
And -- oh yeah, I've got 4 or 5 other methods which I want to be templated 
for the same set of types!

At which point my class degenerates into four pages of mixins and aliases. 
I might as well just copy-and-paste the functions and change the parameter 
type; it'd be a lot clearer.

What a mess.  There has to be a better way to do this.  I'm thinking 
something like

mixin func = FuncTemplate!(int).func;
mixin func = FuncTemplate!(float).func;

Kind of an all-in-one mixin/alias without any dummy names, and with a syntax 
similar to import renaming (and, in effect, a sort of similar effect).

Or, maybe mixin scoping could be changed so that unnamed mixins have their 
symbols imported into the local namespace.  After all, if you write:

mixin FuncTemplate!(int);
mixin FuncTemplate!(float);

..

f.func(4); // error, ambiguous - in both !(int) and !(float)

There is _no way_ to disambiguate it unless you use a named mixin - so why 
bother making it ambiguous with unnamed mixins?

Although I see this second proposal as a problem with:

template Temp(T)
{
    T x;
}

mixin Temp!(int);
mixin Temp!(float);

..

writefln(x); // ? ambiguous

Although in this case, I would imagine the normal variable declaration 
semantics would kick in and say that you were redefining x with the !(float) 
mixin. 





More information about the Digitalmars-d mailing list