More specific instantiations

Marco Leise Marco.Leise at gmx.de
Tue Feb 14 06:36:30 PST 2012


Am 14.02.2012, 13:32 Uhr, schrieb bearophile <bearophileHUGS at lycos.com>:

> Any way, the post was mostly about the @templated() (and not much about  
> the not so useful "static static" idea), that's useful when you define a  
> class template or struct template on several template arguments, and  
> some of its methods use only a subset of the template arguments.
>
> Bye,
> bearophile

I was thinking that "@templated(...)" isn't necessary, since it can be  
deduced naturally from the used symbols inside the function/template/etc.  
to the end that it would just be a compiler optimization.

1. Use all template arguments as usual (in this case of the struct/class)  
for generating the inner template (a method in this case)
2. While generating the method, keep track of used templated symbols from  
the outer scope.
3. For later reference, tag the generated method with template arguments  
introduced by the symbols from step 2.

This can yield sets like those for a struct with 3 template arguments and  
an imaginary method:
char, 5, int  // for "Foo!(char, 5, int)
char, 3, int  // for "Foo!(char, 3, int)
char, 1       // for "Foo!(char, 1, int)
The last case shows, that a "static if" inside the templated method caused  
the third argument to be ignored. The next time, the compiler sees the  
method template instantiated for (char, 1, ubyte), it will match this with  
the existing tag (char, 1).

To illustrate that I have this struct here:

struct Foo(U, V, W) {
   W idx;
   union {
     U[] arr;
     U noarr;
   }
   U bar() {
     static if (V == 1) {
       return noarr;
     } else {
       return arr[idx];     // idx of templated type 'W' is introduced
     }
   }
   W get_idx() {            // uses only symbols of type 'W'
     return idx;            // no need to template on 'U' & 'V'
   }
}


More information about the Digitalmars-d mailing list