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