Function templates with auto ref
parameters can’t be explicitly instantiated, but must be IFTI’d to infer ref
-ness of auto ref
parameters.
When doing meta-programming, that is annoying. Some template might have verified that some alias refers to a function template and that it can be called with the kinds of arguments the template wants to use. Great job, D, for making this rather easy! However, for some reason, we need a function pointer (or delegate) to the respective instance. That is always possible, except if the alias is to a function template with auto ref
parameters.
We should find a solution to this. It does not have to be pretty, there should be just some way to do it.
The ideal test case is a function template with a sequence parameter and auto ref
on non-template-argument-type parameters:
void example(Ts...)(auto ref int arg, auto ref Ts args) { }
auto fp = &example/*YOUR IDEA*/;
One way I thought could work is just passing ref T
: example!(ref long)
, but that doesn’t work for the int
parameter.
While I think the following looks okay, it occupies the syntax ![]
which we might use for something more useful:
auto fp1 = &example![ref](); // void function(ref int)
auto fp2 = &example![auto](); // void function(int)
auto fp1 = &example; // void function(ref int, char, ref wchar)
auto fp2 = &example; // void function(int, ref char, wchar)
While required for explicit function template instantiation, even IFTI can profit from it: Not every lvalue argument should be passed by reference.
int x;
example(x); // Full IFTI: `ref`, Ts empty
example!()(x); // Partial IFTI: infers `ref`, Ts empty, same as above
example![ref]()(x); // No IFTI: `ref` explicit, Ts empty, same as above
example![auto]()(x); // No IFTI: `auto` means not `ref`. Pass `x` by value/copy