Brainstorming: Explicit instantiation of function template with `auto ref` parameters

Quirin Schroll qs.il.paperinik at gmail.com
Thu Feb 20 23:24:10 UTC 2025


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:
```d
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:

```d
auto fp1 = &example![ref](); // void function(ref int)
auto fp2 = &example![auto](); // void function(int)

auto fp1 = &example![ref, auto, ref](char, wchar); // void 
function(ref int, char, ref wchar)
auto fp2 = &example![auto, ref, auto](char, wchar); // 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.
```d
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

```


More information about the Digitalmars-d mailing list