D2: Template as an alias to another template instance

Stanislav Blinov stanislav.blinov at gmail.com
Mon Dec 28 12:23:28 PST 2009

Steven Schveighoffer wrote:

[irrelevant text cut out]
>> ...I'm having some difficulties. Consider this code:
>> ---
>> struct Templ(int N,T){}
>> template Templ1(T)
>> {   
>>     alias Templ!(1,T) Templ1;
>> }
>> void foo2(T)(Templ1!T t){}
>> void main()
>> {
>>     Templ1!(float) t1f1;
>>     foo2(t1f1); // this doesn't compile
>> }
>> ---
>> 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))
>> ---
>> 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. 
> 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.

Yeah, the error message issued by the compiler that contained type name 
sort of confused me, because I couldn't understand how the compiler that 
knows the type is float cannot deduce this float :)

> 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;
>   else
>      alias Templ!(1, int) Templ1;
> }

That's one mean example. But it demonstrates the point right to the 
core. I actually came up with similar one myself while I was trying to 
figure out a workaround after my initial post, and that was when I 
realized life's not so easy with this case. Though I didn't quite get 
exactly why it doesn't work. Now after your explanation I finally got 
the point.

> 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.

Well, that's sad, but what one can do?.. For now, I'll have to live with 
that I guess, despite my function declarations will be a total mess :)

Thanks a lot for your reply and explanation, Steven. I think I should 
force myself to stand in compiler shoes more often.
And thanks Tomek, for pointing out about 'bug'. Your quick response 
somewhat relieved me of the itchy thought that it was I who made 
something terribly wrong (well, actually I see that it was wrong in a 
way - I just demanded too much from the compiler).

More information about the Digitalmars-d-learn mailing list