More specific instantiations

Timon Gehr timon.gehr at gmx.ch
Tue Feb 14 06:46:01 PST 2012


On 02/14/2012 03:36 PM, Marco Leise wrote:
> 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'
> }
> }

It cannot be a compiler optimization because it potentially changes the 
semantics of the code:

template T(U, V, W){
     @templated(W) W idx;
}

void main(){
     T!(int,double,long).idx = 1;
     assert(T!(double,int,long).idx == 1);
}



More information about the Digitalmars-d mailing list