Thread overview
Is it possible to convert a delegate into a function?
Feb 06, 2014
Gary Willoughby
Feb 06, 2014
Dicebot
Feb 06, 2014
Chris Williams
Feb 06, 2014
Chris Williams
February 06, 2014
I know you can convert functions into delegates using: http://dlang.org/phobos/std_functional.html#.toDelegate but can you do this the other way around?

I have a method that needs a function pointer but it would be nice to use a converted delegate pointer instead.
February 06, 2014
On Thursday, 6 February 2014 at 21:26:06 UTC, Gary Willoughby wrote:
> I know you can convert functions into delegates using: http://dlang.org/phobos/std_functional.html#.toDelegate but can you do this the other way around?
>
> I have a method that needs a function pointer but it would be nice to use a converted delegate pointer instead.

auto toFunction(DG)(DG dg)
{
	assert(!dg.ptr);
	return dg.funcptr;
}

void foo(int function() input)
{
	import std.stdio;
	writeln(input());
}

void main()
{
	int boo()
	{
		return 42;
	}
	
	// foo(&boo); // fails
	foo(toFunction(&boo)); // prints "42"
}
February 06, 2014
On Thursday, 6 February 2014 at 21:26:06 UTC, Gary Willoughby wrote:
> I know you can convert functions into delegates using: http://dlang.org/phobos/std_functional.html#.toDelegate but can you do this the other way around?
>
> I have a method that needs a function pointer but it would be nice to use a converted delegate pointer instead.

A function is the address of a block of code in memory. A delegate also has the address to a block of code (a function) but it also has the pointer to an object that is to be passed as the first parameter to the function.

It's pretty easy to drop a parameter, so writing a wrapper method that passes all the other parameters on to the target function is pretty easy.

But unless the function that you're calling can accept a reference to the object that the delegate references and use that and the function pointer to reconstruct the delegate, you're definitely out of luck. Whether there is a means to manually construct a delegate or not, I'm not sure.
February 06, 2014
On Thursday, 6 February 2014 at 22:15:00 UTC, Dicebot wrote:
> 	assert(!dg.ptr);

Note that Dicebot's version works only because he chose a delegate that points to something that doesn't need an external state. The below method, Foo.dump(), would fail the assert because it requires a reference to an instance of Foo in order to grab the state of a.value or b.value.

It does look like one is allowed to write into the delegate .ptr and .funcptr variables, so reconstructing a delegate from parts is possible. (I'm surprised that the definition of funcptr is "void function()" instead of "void function(Foo)"?).


import std.stdio;

class Foo {
private:
    int value;

public:
    this(int v) {
        value = v;
    }

    void dump() {
        writeln(value);
    }
}

void doDump(void* obj, void function() func) {
    void delegate() dg;
    dg.ptr = obj;
    dg.funcptr = func;
    dg();
}

void main() {
    Foo a = new Foo(42);
    Foo b = new Foo(255);

    auto dgA = &a.dump;
    auto dgB = &b.dump;

    writefln("%x %x", dgA.funcptr, dgB.funcptr); // Same

    void function() func = dgA.funcptr;

    doDump(dgA.ptr, func);
    doDump(dgB.ptr, func);
}