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

Paul Backus snarwin at gmail.com
Fri Feb 21 14:07:48 UTC 2025


On Thursday, 20 February 2025 at 23:24:10 UTC, Quirin Schroll 
wrote:
> 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.

It seems to me like this is a general problem with IFTI and/or 
overload resolution, not just `auto ref`. For example, suppose we 
use separate overloads instead of `auto ref`:

     template fun(T)
     {
         void fun(    T x,     T y) {}
         void fun(ref T x,     T y) {}
         void fun(    T x, ref T y) {}
         void fun(ref T x, ref T y) {}
     }

In this example, `fun` is callable using IFTI with any 
combination of lvalue and rvalue arguments, but obtaining a 
pointer to the specific overload of `fun` that's called for a 
given argument list is, let's say, non-trivial.

So, given the above, here's my proposed solution for this entire 
class of problems:

     int lvalue;
     enum int rvalue = 123;

     auto fp = &__traits(resolve, fun(lvalue, rvalue));
     // fp == &fun!int.fun(ref int, int)

`__traits(resolve)` takes a function call expression as its 
argument, and returns an alias to the function symbol that would 
be called by that expression, with both IFTI and overload 
resolution taken into account. If either IFTI or overload 
resolution fail, `__traits(compiles)` also fails--errors are not 
gagged.


More information about the Digitalmars-d mailing list