www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - something cool: templated typedefs

reply Sean Kelly <sean f4.ca> writes:
It just occurred to me this morning to see if I could get templated typedefs to
work in D.  This is at the top of my wish list for C++ and I was excited to see
that they already work in D.  Here's an example:

# class Map(T,U)
# {
#     T key;
#     U val;    
# }
# 
# template IntMap(U)
# {
#     alias Map!(int,U) IntMap;
# }
# 
# int main()
# {
#     Map!(char, char) cmap = new Map!(char, char)();
#     IntMap!(char) imap = new IntMap!(char)();
#     
#     printf( "%.*s\t%.*s\n%.*s\t%.*s\n",
#             typeid( typeof( cmap.key ) ).toString(),
#             typeid( typeof( cmap.val ) ).toString(),
#             typeid( typeof( imap.key ) ).toString(),
#             typeid( typeof( imap.val ) ).toString() );
#    return 0;
# }

prints:

char    char
int     char

I'm really starting to like the way D handles templates.  This auto-collapsing
of template names is starting to look *very* useful.


Sean
Jul 22 2004
parent reply Sha Chancellor <schancel pacific.net> writes:
In message <cdovkl$v8f$1 digitaldaemon.com> 
 Sean Kelly <sean f4.ca> wrote: 

that they already work in D.  Here's an example:

# class Map(T,U)
# {
#     T key;
#     U val;    
# }
# 
# template IntMap(U)
# {
#     alias Map!(int,U) IntMap;
# }
# 
# int main()
# {
#     Map!(char, char) cmap = new Map!(char, char)();
#     IntMap!(char) imap = new IntMap!(char)();
#     
#     printf( "%.*s\t%.*s\n%.*s\t%.*s\n",
#             typeid( typeof( cmap.key ) ).toString(),
#             typeid( typeof( cmap.val ) ).toString(),
#             typeid( typeof( imap.key ) ).toString(),
#             typeid( typeof( imap.val ) ).toString() );
#    return 0;
# }

prints:

char    char
int     char

I'm really starting to like the way D handles templates.  This auto-collapsing
of template names is starting to look *very* useful.

Why is it you can do imap.key and imap.val. Shouldn't this need to be done like: IntMap!(char).IntMap imap = new IntMap!(char).IntMap. Or is there some special thing going on when there's an alias to something with the same name as a template? I thought templates had their own namespace.. What's going on here seems very mystical to me. Right from the template specification: TemplateInstance: template TFoo(T) { alias T* t; } ... TFoo!(int).t x; // declare x to be of type int* A template instantiation can be aliased: template TFoo(T) { alias T* t; } alias TFoo!(int) abc; abc.t x; // declare x to be of type int*
Jul 22 2004
parent Sean Kelly <sean f4.ca> writes:
In article <cdp9pi$13ns$1 digitaldaemon.com>, Sha Chancellor says...
In message <cdovkl$v8f$1 digitaldaemon.com> 
 Sean Kelly <sean f4.ca> wrote: 

that they already work in D.  Here's an example:

# class Map(T,U)
# {
#     T key;
#     U val;    
# }
# 
# template IntMap(U)
# {
#     alias Map!(int,U) IntMap;
# }
# 
# int main()
# {
#     Map!(char, char) cmap = new Map!(char, char)();
#     IntMap!(char) imap = new IntMap!(char)();
#     
#     printf( "%.*s\t%.*s\n%.*s\t%.*s\n",
#             typeid( typeof( cmap.key ) ).toString(),
#             typeid( typeof( cmap.val ) ).toString(),
#             typeid( typeof( imap.key ) ).toString(),
#             typeid( typeof( imap.val ) ).toString() );
#    return 0;
# }

prints:

char    char
int     char

I'm really starting to like the way D handles templates.  This auto-collapsing
of template names is starting to look *very* useful.

Why is it you can do imap.key and imap.val. Shouldn't this need to be done like: IntMap!(char).IntMap imap = new IntMap!(char).IntMap. Or is there some special thing going on when there's an alias to something with the same name as a template? I thought templates had their own namespace.. What's going on here seems very mystical to me.

The key is the section on implicit template properties. The text reads: "if a template has exactly one member in it, and the name of that member is the same as the template name, that member is assumed to be referred to in a template instantiation." ie. # template foo(T) # { # void foo( T t ) {} # } can be called as: # foo!(int)( 5 ); ie. it's the same as doing: # foo!(int).foo(5); The important thing to note is that the standard mentions no restrictions on what the member has to be. So my example: # template IntMap(U) # { # alias Map!(int,U) IntMap; # } would normally be called as: # IntMap!(char).IntMap mymap; but collapses to: # IntMap!(char) mymap; Sean
Jul 22 2004