www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Function aliasing problem

reply Jean-Louis Leroy <jl leroy.nyc> writes:
I can alias a function template:

     T f(T)(T x) { return x; }

     alias g = f;
     int a = g(42);

I can alias a static function:

     struct S
     {
       static int f(int i) { return i; }
     }

     alias sf = S.f;
     int b = sf(42);

I can alias to a static function in a template instance:

     struct SS(T)
     {
       static T f(T i) { return i; }
     }

     alias ssi = SS!int.f;
     int c = ssi(42);

Of course an alias can be templatized:

     alias SSS(T) = SS!T;

I would like to combine them all, e.g.:

     alias sst(T) = SS!T.f;
     int d = sst(42); // <=> SS!int.f(42)

But it fails like this:

     aliasstaticfunction.d(23): Error: template 
`aliasstaticfunction.sst` cannot deduce function from argument 
types `!()(int)`, candidates are:
     aliasstaticfunction.d(22):        `sst(T)`

In fact this simpler attempt fails in the same fashion:

     alias g2(X) = f!X;
     int e = g(42);

     aliasstaticfunction.d(25): Error: template 
`aliasstaticfunction.g2` cannot deduce function from argument 
types `!()(int)`, candidates are:
     aliasstaticfunction.d(24):        `g2(X)`

I tried with an eponymous template declaring an alias, in place 
of the alias template. Unsurprisingly, I get the same error (the 
latter is lowered to the former isn't it?).

I also tried std.meta.Alias, to no avail.

Is there a solution, other than building a templatized forwarder 
function, e.g.:

     T sst(T)(T i) { return SS!T.f(i); }
     int d = sst(42);

(and this is not good anyway, as it drops function attributes, 
parameter storage classes, UDAs etc).
Apr 21 2020
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 4/21/20 5:24 PM, Jean-Louis Leroy wrote:

 I would like to combine them all, e.g.:
 
      alias sst(T) = SS!T.f;
      int d = sst(42); // <=> SS!int.f(42)
 
 But it fails like this:
 
      aliasstaticfunction.d(23): Error: template 
 `aliasstaticfunction.sst` cannot deduce function from argument types 
 `!()(int)`, candidates are:
      aliasstaticfunction.d(22):        `sst(T)`
Implicit *Function* Template Instantiation (IFTI) only works on functions, not types. You are asking the compiler to deduce the template parameter of the struct from its inner function being called. This is similar to constructors on templated types. D just doesn't do that currently. You need a forwarder. -Steve
Apr 21 2020