Address of a lambda
ag0aep6g via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Fri Jul 7 11:01:59 PDT 2017
On 07/07/2017 07:33 PM, FoxyBrown wrote:
> In gtk, we routinly have to use delegates for callbacks. But the methods
> that accept these delegates want the address of the delegate,
I don't think that's true. As far as I can tell, this is the signature
of addOnDelete [1]:
----
gulong addOnDelete(bool delegate(Event, Widget) dlg, ConnectFlags
connectFlags=cast(ConnectFlags)0)
----
`dlg` is just a delegate, not a pointer to a delegate.
> this
> prevents us from being able to pass a lambda in directly, but there
> really is not reason why we shouldn't be able to do this?
>
> Fine:
> void main()
> {
> bool windowDelete(Event event, Widget widget) { Main.quit(); return
> false; }
> MainWindow.addOnDelete(&windowDelete);
> }
Here you're "taking the address" of a method. The result is a delegate,
not a pointer to a delegate. The delegate is the address/pointer (plus
another pointer to some related context).
> Invalid:
>
> void main()
> {
> MainWindow.addOnDelete(&((Event event, Widget widget) { Main.quit();
> return false; }));
> }
Remove the `&` operator and it should work. The function literal [2]
already makes a delegate.
> and yet, the only difference is a copy and paste(i.e., a rewrite rule,
> at most). Surely the compiler can figure out that we can take such an
> address because anything that actually exists must have an address
> somewhere.
Stuff can exist in registers only. In a function call `f(42)`, 42 likely
goes directly into a register, not into memory.
> Seems like an arbitrary blocker? Even if it saves us from
> some obscure problems, it should work in most cases and be allowed when
> used in those cases.
>
> What's even stranger is that the function windowDelete must be declared
> in some type of object, such as another function, so it is actually a
> delegate, if one has it in the module root then it is a normal function
> and cannot be passed to addOnDelete, even though, again, there is very
> little difference.
Yeah, that's an interesting oddity. The problem is that the parameters
of a `void delegate(int foo, int bar)` are possibly passed differently
from those of a `void function(int foo, int bar)`.
Related thread:
http://forum.dlang.org/post/ofc0lj$2u4h$1@digitalmars.com
[...]
> I do know the difference between a delegate and a function, and I
> suppose addOnDelete should be defined to take a function instead?
If anything, it should accept both. Not a function instead of a delegate.
> But
> how can we create a "delegate function" similar to the nested delegate
> in the first case that works so that we can pass them as delegates?
http://dlang.org/phobos/std_functional.html#toDelegate
[1]
https://github.com/gtkd-developers/GtkD/blob/5c2ee83aae7425b683709593c5fd44a7ab1db067/generated/gtkd/gtk/Widget.d#L6793
[2] https://dlang.org/spec/expression.html#function_literals
More information about the Digitalmars-d-learn
mailing list