Generalizing over function pointers and delegates

Alex sascha.orlov at gmail.com
Fri Feb 15 14:30:45 UTC 2019


On Friday, 15 February 2019 at 14:20:44 UTC, Bastiaan Veelo wrote:
> Given a function taking a delegate, for example
>
> ```
> int fun(int delegate() dg) {return dg();}
> ```
>
> Sometimes we need to call `fun` with a pointer to a nested 
> function and other times with a pointer to a top level 
> function. As function pointers do not implicitly convert to 
> delegates, this does not work without jumping through hoops.
>
> One option is to define an overload:
>
> ```
> int fun(int function() fn)
> {
>     int nested_fn()
>     {
>         return fn();
>     }
>     return fun(&nested_fn);
> }
> ```
>
> This is clunky and rather a lot of extra lines to work around a 
> language limitation. The limitation seems somewhat artificial, 
> because a delegate /can/ be initialized referencing a top level 
> function (the spec [1] limits that to delegate declarations at 
> module scope, but this limit does not seem to apply [2]). But 
> you cannot /assign/ it a top level function. You can however 
> explicitly assign the `.funcptr` referencing the top level 
> function, leaving the stack frame pointer null.
>
> Exploiting this, it is possible to explicitly convert a 
> function pointer into a delegate [2]:
> ```
> Ret delegate(Args args) fun_to_dlg(Ret, Args...)(Ret 
> function(Args args) fun)
> {
>     Ret delegate(Args) dlg;
>     dlg.funcptr = fun;
>     return dlg;
> }
> ```
>
> allowing
> ```
> int top_level() {return -1;}
> void main()
> {
>     assert(fun(fun_to_dlg(&top_level)) == -1);
> }
> ```
>
> This may be preferable to the overload, depending on the number 
> of calls like this. But since this is allowed and working, why 
> can't it be done automatically? Or, when implicit conversion is 
> dangerous, why doesn't a cast exist to the effect of my 
> template? Have I overlooked an easier way of doing this?
>
> Thanks for any input!
> Bastiaan.
>
> P.S. For the record, the spec also says this: "Future 
> directions: Function pointers and delegates may merge into a 
> common syntax and be interchangeable with each other." I wish 
> that was the case already.
>
> [1] Point 9 in https://dlang.org/spec/function.html#closures
> [2] https://run.dlang.io/is/x8HJaW

There is
https://dlang.org/library/std/functional/to_delegate.html



More information about the Digitalmars-d-learn mailing list