On Thu, 10 Feb 2011 08:39:13 -0500, spir <[email protected]> wrote:

On 02/09/2011 11:05 PM, Steven Schveighoffer wrote:

I don't think you want templates. What you want is a tagged union (and a struct
is MUCH better suited for this):

// untested!

struct Example
{
private
{
bool isDelegate;
union
{
void function() fn;
void delegate() dg;
}
}

void setCallback(void function() f) { this.fn = f; isDelegate = false;}
void setCallback(void delegate() d) { this.dg = d; isDelegate = true;}

void opCall()
{
if(isDelegate)
dg();
else
fn();
}
}

Waow, very nice solution.
I really question the function/delegate distinction (mostly artificial, imo) that "invents" issues necessiting workarounds like that. What does it mean, what does it bring?

A function pointer is compatible with a C function pointer. C does not have delegates, so if you want to do callbacks, you need to use function pointers. There is no way to combine them and keep C compatibility.

Right, there is one pointer less for funcs. This save 4 or 8 bytes, so to say, nothing; who develops apps with arrays of billions of funcs? There are written in source ;-) Even then, if this saving of apointer was of any relevance, then it should be an implementation detail that does not leak into artificial semantic diff, creating issues on the programmer side. What do you think?

What you want is already implemented. There is a relatively new phobos construct that builds a delegate out of a function pointer. In fact, my code could use it and save the tag:


// again, untested!

import std.functional : toDelegate;

struct Example
{
   private void delegate() dg;

   void setCallback(void function() f) { this.dg = toDelegate(f); }
   void setCallback(void delegate() d) { this.dg = d; }

   void opCall() { dg(); }
}

Note that toDelegate doesn't appear on the docs because of a doc generation bug...

-Steve

Reply via email to