digitalmars.D.bugs - BUG: Mixin' same template twice
- Garett Bass (26/26) Nov 07 2005 It may often be advantageous to reuse an algorithm for a variety of type...
- Regan Heath (16/36) Nov 07 2005 Changing the templates to:
- Ivan Senji (16/38) Nov 07 2005 Changing Bar to:
- Garett Bass (37/37) Nov 08 2005 Ok, I've redesigned my test case to include the suggested workaround (cl...
- Garett Bass (29/29) Nov 08 2005 So, it turns out that the ugly is even uglier than I thought. The mixin...
It may often be advantageous to reuse an algorithm for a variety of types, however this cannot currently be done via templates and mixins: ------------------------- private import std.stdio; template f(T) { T f(T x, T y) { return x + y; } } template g(T) { T g(T x, T y) { return x - y; } } class Bar { mixin f!(int); // Ok mixin g!(int); // Ok //mixin f!(float); // Error: mixin f is not a template //mixin g!(float); // Error: mixin g is not a template } alias f!(int) fi; alias f!(float) ff; int main(char[][] args) { writefln("%d", fi(1, 2)); // Ok writefln("%f", ff(1.5, 2.5)); // Ok return 0; } ------------------------- Regards, Garett
Nov 07 2005
On Mon, 7 Nov 2005 21:53:26 -0600, Garett Bass <garettbass studiotekne.com> wrote:private import std.stdio; template f(T) { T f(T x, T y) { return x + y; } } template g(T) { T g(T x, T y) { return x - y; } } class Bar { mixin f!(int); // Ok mixin g!(int); // Ok //mixin f!(float); // Error: mixin f is not a template //mixin g!(float); // Error: mixin g is not a template } alias f!(int) fi; alias f!(float) ff; int main(char[][] args) { writefln("%d", fi(1, 2)); // Ok writefln("%f", ff(1.5, 2.5)); // Ok return 0; }Changing the templates to: template f(T) { T fa(T x, T y) { return x + y; } } template g(T) { T ga(T x, T y) { return x - y; } } or anything other than 'f' and 'g' fixes the problem. I guessed this because giving the mixin a scope name changes the error, see: mixin f!(float) a; //abug.Bar.f!(float) a f is not a template (abug.d was my source file name) Not sure if any of that helps. Regan
Nov 07 2005
Garett Bass wrote:It may often be advantageous to reuse an algorithm for a variety of types, however this cannot currently be done via templates and mixins: ------------------------- private import std.stdio; template f(T) { T f(T x, T y) { return x + y; } } template g(T) { T g(T x, T y) { return x - y; } } class Bar { mixin f!(int); // Ok mixin g!(int); // Ok //mixin f!(float); // Error: mixin f is not a template //mixin g!(float); // Error: mixin g is not a template }Changing Bar to: class Bar { mixin f!(int); // Ok mixin g!(int); // Ok mixin .f!(float); // Error: mixin f is not a template mixin .g!(float); // Error: mixin g is not a template } Will make it compile but will cause ambiguity errors when method is called. Change it to this to make it work: class Bar { mixin .f!(int) f1; mixin .f!(float) f2; alias f1.f f; alias f2.f f; }
Nov 07 2005
Ok, I've redesigned my test case to include the suggested workaround (class Ugly). This seems reasonable, though it would be nice if mixin could do the extra work automatically. ------------ module test; private import std.stdio; template F(T) { T f(T x, T y) { return x + y; } } class Good { mixin F!(int); } class Bad { mixin F!(int); mixin F!(float); } class Ugly { private mixin F!(byte) fb; private mixin F!(int) fi; private mixin F!(float) ff; public alias fb.f f; public alias fi.f f; public alias ff.f f; } int main(char[][] args) { Good good = new Good; writefln("%d", good.f(1, 2)); // Ok Bad bad = new Bad; //writefln("%d", bad.f(1, 2)); // Error //writefln("%f", bad.f(1.5, 2.5)); // Error Ugly ugly = new Ugly; writefln("%d", ugly.f(1, 2)); // Ok writefln("%f", ugly.f(1.5, 2.5)); // Ok return 0; } ------------ Regards, Garett
Nov 08 2005
So, it turns out that the ugly is even uglier than I thought. The mixins have to be public in order for public aliases to be visible to other modules, which means that the uglified mixin identifiers are polluting the class interface. ------------------------- module ugly; template F(T) { T f(T x, T y) { return x + y; } } class Ugly { public mixin F!(byte) fb; public mixin F!(int) fi; public mixin F!(float) ff; public alias fb.f f; public alias fi.f f; public alias ff.f f; } ------------------------- module main; private import std.stdio; int main(char[][] args) { Ugly ugly = new Ugly; writefln("%d", ugly.f(1, 2)); // Ok writefln("%f", ugly.f(1.5, 2.5)); // Ok writefln("%d", ugly.fi(1, 2)); // UGLY! writefln("%f", ugly.ff(1.5, 2.5)); // UGLY! return 0; } ------------------------- Regards, Garett
Nov 08 2005