delegate cannot handle polymorphism?
Nub Public
nubpublic at gmail.com
Mon Jun 27 19:23:32 PDT 2011
On 6/28/2011 1:29 AM, Timon Gehr wrote:
> Nub Public wrote:
>> On 6/27/2011 7:08 PM, Michel Fortin wrote:
>>> On 2011-06-27 03:30:09 -0400, Nub Public<nubpublic at gmail.com> said:
>>>
>>>> class BOn 6/27/2011 7:08 PM, Michel Fortin wrote:
>>> On 2011-06-27 03:30:09 -0400, Nub Public<nubpublic at gmail.com> said:
>>>
>>>> class B
>>>> {
>>>> void fun() { writeln("B"); }
>>>> }
>>>>
>>>> class D : B
>>>> {
>>>> override void fun() { writeln("D"); }
>>>> }
>>>>
>>>> void delegate() dg =&b.fun;
>>>> dg.ptr = cast(void*)d;
>>>> dg();
>>>>
>>>>
>>>> Compiler: DMD 2.053
>>>> It prints "B" instead of "D".
>>>> The equivalent code in C++ prints "D" nicely.
>>>
>>> C++ doesn't have delegates, and D doesn't have member function pointers.
>>> Resolving virtual functions is done while you take its address in D,
>>> while in C++ the member function pointer type contains holds the vtable
>>> offset (or several in the case of multiple inheritance) which gets
>>> resolved only when you call the function.
>>>
>>> If you want the C++ behaviour, try using a delegate literal as a
>>> trampoline that gets the object as a parameter to then call your function:
>>>
>>> void delegate(B b) dg = (B b) { b.fun(); };
>>>
>>> dg(d);
>>>
>>
>>
>> Thank you. That was very helpful.
>>
>> What's the rational for this behavior though? Resolving the address of a
>> virtual function at compile time seems a little counter-intuitive to me.
>> I guess this way is slightly more efficient.
>
> A delegate literal consists of a function pointer and a context pointer. There is
> no polymorphism in that. A member function is a normal function you can take the
> address of.
I see.
> In general, you shouldn't update one of (ptr,funcptr) without updating the other
> unless you have good reasons to do so and know exactly what you are doing.
> Not having member pointers is AFAIK a direct consequence of the fact that nobody
> uses them in C++ and almost nobody even knows that they exist.
> Furthermore, their implementation is too involved, given their limited usefulness.
>
> Cheers,
> -Timon
I have to disagree on this.
Member function pointers are useful in many event handling systems.
Imagine a signal and slot system. To register a member function as a
slot, the most direct and intuitive way is to take a member function
pointer. In c++0x and boost, <function>, <functional> and related
libraries all work with member function pointers.
My premise is simple: a virtual function should always be resolved by
the dynamic identity of the object, regardless of whether it is called
directly or through a function pointer.
Perhaps the contextptr of D delegate cannot do this because it can refer
to the enclosing context besides an object. But I'd love it for D to
have the functionality of a truly polymorhic member function pointer.
Maybe the restrictions on the keyword "function" can be relaxed to work
with such a pointer?
More information about the Digitalmars-d
mailing list