Am 14.02.2012, 13:32 Uhr, schrieb bearophile <[email protected]>:
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'
}
}