On Saturday, 8 October 2022 at 23:06:13 UTC, Anonymouse wrote:
I have some nested templated code that takes function pointers.
In many cases I pass it functions of identical signatures,
except some are `@safe` and others are `@system`. In those
cases the templates end up getting instantiated twice. I don't
care about the `@safe`-ness and I'd really like to just have
them all treated as `@system`, with one instantiation per
unique signature.
...
But surely there has to be a better way?
You might be templating more information than necessary. In your
example `foo` doesn't need to be a template at all:
```D
void foo(void function() @system fun) {
pragma(msg, typeof(fun).stringof);
}
```
If your real code needs to template the return type and
parameters of `fun`, for example, consider just templating those
instead of the whole function pointer type:
```D
void foo(R, P...)(R function(P) @system fun) {
pragma(msg, typeof(fun).stringof);
}
```
(Things do get awkward with `ref` and `out`, though, because D
considers them to be part of the function's type rather than part
of the parameter or return types. `ref` is the bane of my D
meta-programming existence.)