On 10 June 2013 21:35, Jacob Carlborg <doob@me.com> wrote:
On 2013-06-10 11:45, Manu wrote:

A function pointer is a pointer. A delegate is a pointer to a function
and a context pointer, ie, 2 pointers.
A pointer to a method is just a pointer to a function, but it's a
special function which receives a 'this' argument with a special calling
convention.
It's definitely useful to be able to express a 'thiscall' function pointer.

It's not very useful without the context pointer, i.e. "this".

You supply 'this' at the time of calling. Read my OP.

        Also, extern(C++) delegates are useful too in their own right


    To do what? As far as I know C++ doesn't have anything corresponding
    to a D delegate.


C++ has FastDelegate, which I use to interact with D delegates all the
time! ;)

I didn't know about that. Is that something that is in the language or standard library?

It's Don's work of art. It's also how I came to find out about D in the first place ;)

extern(C++) delegate is required to specify the appropriate calling
convention, otherwise it's just a delegate like usual.

I see.


I'm just trying to show that sometimes you don't want a delegate, you
just want a function pointer.

Then use a function pointer.

There's no way to specify to use the 'thiscall' calling convention.
What I propose is a syntax that would describe a member function pointer, and imply the appropriate calling convention.

delegate's contain the function pointer I'm after, so I can access it
indirectly, but it's just not so useful. It's not typed (is void*), and
you can't call through it.

The function pointer of a delegate is typed, it's the context pointer that is void*.

Sorry, I'm just trying to understand what you're doing, what problems you have. You can compose and decompose delegates using its built-in properties "ptr" and "funcptr".

You can do something like:

class Foo
{
    int i;

    void a () { writeln("Foo.a i=", i); }
    void b () { writeln("Foo.b i=", i); }
}

void main ()
{
    auto f1 = new Foo;
    f1.i = 3;
    auto dg = &f1.a;
    dg();

    auto f2 = new Foo;
    f2.i = 4;
    dg.ptr = cast(void*) f2;
    dg();

    dg.funcptr = &Foo.b;
    dg();
}

The only thing that doesn't work with the above is if I change the context pointer to a subclass of Foo which overrides the method I want to call. It will still call the method in Foo unless I change "funcptr".

I wouldn't say that doesn't work, I'd say that works perfectly. A delegate is just a 'this' and function pair. If you change 'this', there's no reason the function should change.

funcptr pretends to be typed, but the type is just wrong. In your example, the type is 'void function()', it should be 'void function(Foo this)'.
So it's actually a lie. You can't call it. I'm not sure why it's typed at all... just a crash waiting to happen.
So what I'm suggesting is a syntax to express a member function pointer, and then it could be properly typed.