D2: Template as an alias to another template instance

Steven Schveighoffer schveiguy at yahoo.com
Mon Dec 28 05:41:25 PST 2009

On Thu, 24 Dec 2009 12:45:41 -0500, Stanislav Blinov  
<stanislav.blinov at gmail.com> wrote:

> Hello,
> I'm trying to make a template that would be an alias to another template  
> instance (sort of a shortcut), but I'm having some difficulties.  
> Consider this code:
> ---
> import std.stdio;
> struct Templ(int N,T){}
> alias Templ!(1,float) Templ1f;
> template Templ1(T)
> {	
> 	alias Templ!(1,T) Templ1;
> }
> void foo1(T)(Templ!(1,T) t){}
> void foo2(T)(Templ1!T t){}
> void main()
> {
> 	Templ1f t1f;
> 	Templ1!(float) t1f1;
> 	foo1(t1f);
> 	foo2(t1f1); // this doesn't compile
> 	// foo2(t1f); // this won't compile either
> }
> ---
> Unfortunately, dmd 2.032 on Windows and 2.037 on Linux both give me this  
> error:
> ---
> templ.d(21): Error: template templ.foo2(T) does not match any function  
> template declaration
> templ.d(21): Error: template templ.foo2(T) cannot deduce template  
> function from argument types !()(Templ!(1,float))
> ---
> I had an impression that aliasing employed in Templ1 would effectively  
> make Templ1 work as a type (a shortcut to Templ!(1,T)), but I don't get  
> this behvior.
> Now, I'm not lazy to declare functions with parameters having full  
> template instance names. It's just that sometimes function declaration  
> will be obvious (or at least cleaner) if its parameters have shorter but  
> meaningful type names instead of generic name with a set of properties  
> (that is, a template name with a full set of template parameters).
> Is there something wrong with my code, am I missing something perhaps?

The issue is that the compiler has trouble deducing how to construct the  
right template from the arguments.  Implicit Function Template  
Instantiation (IFTI) works only on direct template instantiations, going  
through aliases is difficult because it cannot figure out how to get from  
A to B.

There is an open bugzilla that might fix this:  

Taking your example foo1, the compiler is given a struct Templ1!(float),  
but it has to match argument Templ!(1, T).  A person can see that if you  
plug in float for T, you get to the same result, but this sort of  
backwards deduction doesn't exist in the compiler.  Because the template  
can contain *anything*, i.e. you could have something like this:

template Templ1(T)
   static if(is(T == int))
      alias Templ!(1, float) Templ1;
      alias Templ!(1, int) Templ1;

If templ1 looked like this, how would the compiler deduce that it has to  
plug in 'int' for T in order to get the right result?  The proposed  
solution in bug 1807 says that in the most simple cases where the template  
is just an alias, the compiler should reduce the template argument type to  
the alias.  Even with this fix, my insane example wouldn't work with IFTI  

I think there is a lot more work that can be done on IFTI, and it's  
probably low on the todo list because it's not critical to get done before  
the book comes out.


More information about the Digitalmars-d-learn mailing list