How to declare "type of function, passed as an argument, which should have it's type inferred"? (or if D had an "any" type)

Paul Backus snarwin at gmail.com
Mon Mar 29 16:31:49 UTC 2021


On Monday, 29 March 2021 at 16:20:59 UTC, Ali Çehreli wrote:
> auto myFunc(F)(string name, F func)
> {
>   // This condition could be a template constraint but they 
> don't
>   // support error messages.
>   static assert (is (Parameters!func == AliasSeq!(string)),
>                  "'func' must be a callable that takes 
> 'string'.");
>   return func(name);
> }
>
> void main() {
>   // One trouble with this "solution" is that for the compiler 
> to
>   // know the return type of the lambda, the parameter must be
>   // declared as 'string' (in this case).
>   writeln(myFunc("foo", (string a) => a ~ '.'));
> }
>
> Ali

Alternatively:

     auto myFunc(F)(string name, F func)
     {
       static assert (__traits(compiles, (string s) => func(s)),
                      "'func' must be a callable that takes 
'string'.");
       return func(name);
     }

     void main() {
       // No need to write out the argument type
       writeln(myFunc("foo", a => a ~ '.'));
     }

You can generalize this into a helper template:

     enum bool isCallableWith(alias fun, ArgTypes...) =
       __traits(compiles, (ArgTypes args) => fun(args));

Usage:

     static assert(isCallableWith!(func, string));


More information about the Digitalmars-d-learn mailing list