www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Double face templates

reply bearophile <bearophileHUGS lycos.com> writes:
I have created several templates, like one very simple named ArrayType1 that
given the type of an array becomes an alias of the type of its items (there are
other more complex templates too).

They can be used as:
ArrayType1!(TypeArray)
or:
ArrayType1!(typeof(somearray))

But to reduce code clutter if possible I'd like to create a template that works
in both cases:
ArrayType1!(TypeArray)
ArrayType1!(somearray)

I know template "arguments" can be an alias too, so I may define a pair like
this:
template ArrayType1!(T) {...}
template ArrayType1!(alias x) { ... }
but when I define both templates I always enter a swamp, with so many
(sometimes strange) bugs that so far I have always thrown away the template
version with alias and I have kept only the more normal template defined on a
type.

Is what I am trying to do wrong/ unsafe/ philosophically bad?
If my purpose isn't bad, then can you suggest how to implement it much more
reliably?

Thank you,
bearophile
Sep 29 2008
parent reply BCS <ao pathlink.com> writes:
Reply to bearophile,

 I have created several templates, like one very simple named
 ArrayType1 that given the type of an array becomes an alias of the
 type of its items (there are other more complex templates too).
 
 They can be used as:
 ArrayType1!(TypeArray)
 or:
 ArrayType1!(typeof(somearray))
 But to reduce code clutter if possible I'd like to create a template
 that works in both cases:
 ArrayType1!(TypeArray)
 ArrayType1!(somearray)
 I know template "arguments" can be an alias too, so I may define a
 pair like this:
 
 template ArrayType1!(T) {...}
 
 template ArrayType1!(alias x) { ... }
 
 but when I define both templates I always enter a swamp, with so many
 (sometimes strange) bugs that so far I have always thrown away the
 template version with alias and I have kept only the more normal
 template defined on a type.
 
 Is what I am trying to do wrong/ unsafe/ philosophically bad? If my
 purpose isn't bad, then can you suggest how to implement it much more
 reliably?
 
 Thank you,
 bearophile
you might be able to use a form like this template T(alias a) { static if(is(a)) { // stuff } else alias T!(typeof(a)) T; // or 'mixin T!(typeof(a));' }
Sep 29 2008
parent reply bearophile <bearophileHUGS lycos.com> writes:
BCS:
 you might be able to use a form like this
 template T(alias a)
 {
     static if(is(a))
     {
        // stuff
     }
     else
        alias T!(typeof(a)) T;
     // or 'mixin T!(typeof(a));'
 }
I think it doesn't work: import std.stdio; template ArrayType1(T: T[]) { alias T ArrayType1; } template Foo(alias x) { static if(is(x)) alias ArrayType1!(x) Foo; else alias ArrayType1!(typeof(x)) Foo; } void main() { alias string[] Ts; Ts s = ["aaaa", "bb"]; writefln(typeid( Foo!(s) )); writefln(typeid( Foo!(Ts) )); } But it doesn't matter much, I'll keep using just the version of the templates that take a type... Bye and thank you, bearophile
Sep 30 2008
parent Don <nospam nospam.com.au> writes:
bearophile wrote:
 BCS:
 you might be able to use a form like this
 template T(alias a)
 {
     static if(is(a))
     {
        // stuff
     }
     else
        alias T!(typeof(a)) T;
     // or 'mixin T!(typeof(a));'
 }
I think it doesn't work: import std.stdio; template ArrayType1(T: T[]) { alias T ArrayType1; } template Foo(alias x) { static if(is(x)) alias ArrayType1!(x) Foo; else alias ArrayType1!(typeof(x)) Foo; } void main() { alias string[] Ts; Ts s = ["aaaa", "bb"]; writefln(typeid( Foo!(s) )); writefln(typeid( Foo!(Ts) )); } But it doesn't matter much, I'll keep using just the version of the templates that take a type... Bye and thank you, bearophile
It works if you change alias string[] Ts; into a typedef. The reason is that aliases get resolved at a very early stage. There's no difference at all between string[] and Ts, and string is itself an alias, not a typedef. So Ts gets turned into char[][] before template lookup happens. Built-in types can't be alias template parameters, unfortunately. Which kills the "double face template" idea.
Oct 01 2008