Thread overview
get Class from Pointer of member
May 24, 2012
StefanvT
May 24, 2012
Ali Çehreli
May 24, 2012
StefanvT
May 24, 2012
Ali Çehreli
May 24, 2012
Hi,
I'm totally new to D. But it looks very interesting :-)
I normally develop in C++.

I have such a function in C++:

template<class CB,class FIELD>
inline CB* get_class_from_field( FIELD CB::*field, FIELD* mp) {
    return reinterpret_cast<CB*>(
            reinterpret_cast<char*>(mp) -
            reinterpret_cast<ptrdiff_t>(&(reinterpret_cast<CB*>(0)->*field)));
}


Here I come with a pointer to a class member and can calculate the pointer to the class, where the member is within. (Nothing spectacular in c++)

Is this also possible in D?
I noticed that it's not very easy to get a member pointer on the heap. Isn't it?

thank you & best regards,
Stefan
May 24, 2012

On 05/24/2012 05:29 AM, StefanvT wrote:

> I have such a function in C++:
>
> template<class CB,class FIELD>
> inline CB* get_class_from_field( FIELD CB::*field, FIELD* mp) {
> return reinterpret_cast<CB*>(
> reinterpret_cast<char*>(mp) -
> reinterpret_cast<ptrdiff_t>(&(reinterpret_cast<CB*>(0)->*field)));
> }

I think get_object_from_field() would be a better name.

> Here I come with a pointer to a class member and can calculate the
> pointer to the class, where the member is within. (Nothing spectacular
> in c++)
>
> Is this also possible in D?

There are no pointers to members in D. In C++, member pointers carry the offset of the field. The same can be achieved by using the .offsetof property:

class C
{
    int i;
    int j;
}

CB get_object_from_field(CB, FIELD)(size_t offset, FIELD * f)
{
    return cast(CB)(cast(ubyte*)f - offset);
}

void main()
{
    auto c = new C;
    C c2 = get_object_from_field!C(c.j.offsetof, &c.j);
    assert(c2 is c);
}

I am pretty sure there are better solutions for a more specific problem.

Ali

-- 
D Programming Language Tutorial: http://ddili.org/ders/d.en/index.html

May 24, 2012
Hey thank you!! :-)

I already tried to use offsetof on my own. But I always try to
cast to a pointer.
And this fails horribly :o)

So thank you. I think I need to have a deeper look at references
and pointer in D!


May 24, 2012
On 05/24/2012 10:25 AM, StefanvT wrote:
> Hey thank you!! :-)
>
> I already tried to use offsetof on my own. But I always try to
> cast to a pointer.
> And this fails horribly :o)
>
> So thank you. I think I need to have a deeper look at references
> and pointer in D!
>
>

I should have mentioned that pointers to member functions are possible in D as delegates. A delegate keeps the object that it is bound to alive:

import std.stdio;

class C
{
    int i;

    void foo()
    {
        writeln("Called on object at ", &i);
    }
}

alias void delegate() MemberFunc;

MemberFunc return_object_delegate()
{
    auto c = new C;
    c.foo();

    auto d = &c.foo;    // c will be kept alive
    return d;
}

void main()
{
    auto d = return_object_delegate();
    // ... some time later
    d();
}

Ali

-- 
D Programming Language Tutorial: http://ddili.org/ders/d.en/index.html