best D way to port C style array of void*

Steven Schveighoffer schveiguy at yahoo.com
Tue Feb 5 20:17:59 PST 2013


On Tue, 05 Feb 2013 22:16:17 -0500, estew <estewh at gmail.com> wrote:

> Hi All,
>
> I've some old C code which I'm porting to D. It's a learning exercise so  
> I don't want to just wrap the C lib.
>
> I have an array of void* and an array of callbacks that take void*  
> pointers for user data.
>
> I'm wondering what is a good way to port this into D and avoid the  
> void*. My C++ version uses std::function<> for the callbacks and  
> functors. I'm using std::vector<boost::any> For the array of void*.
>
> Maybe it's not the best approach but it's my best efforts. For the D  
> port I'd like to improve on the C++ approach and I'd love to know a  
> better way to do it.
>
> * Could I replace the boost::any with an array of Variant from  
> std.variant?

That is probably what I would recommend.  Although I would consider  
altering the design to avoid this.  D has a much better type system than C  
or C++.

> * Can I assign a struct with opCall() to a function pointer, similar to  
> how std::function<> can take a struct with an operator().
>
> * Should I forget functors and use a callback that takes a std.variant  
> (or whatever the boost::any like thing in D is) instead of void*?

Use a delegate.  A delegate is a function call with a context pointer.  No  
need to specify the type of the pointer, it's whatever type it needs to be.

You can create a delegate just about anywhere.  It can be a member  
function of a class or struct, or an internal function, or a lambda  
function (D supports closures).

e.g.:

import std.stdio;

void callit(void delegate() dg)
{
     // call delegate with context pointer
     dg();
}

void main()
{
     int x;
     auto dg = ()=>writeln(++x); // create a delegate using a lambda  
function
     callit(dg);
     callit(dg);
     callit(dg);
     callit(dg);
}

-Steve


More information about the Digitalmars-d-learn mailing list