Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get outer object pointer inside inner object

There are two objects: Holder and Property. Holder contains Property as a field. I want to get access to Holder from Property. In general case the address of Property will be address of Holder + offset of field of type Property.

But important: the Property should not have any fields (for example I can't pass the Holder to constructor of Property and save it as 'outer').

UPD: I suppose this trick should only work for the standard layout.

UPD2: The main reason why I want to use such approach (do not pass reference to Property) is use minimum memory as possible in Holder object. In best case: sizeof(Property) is 0 bytes (Although the standard does not allow this).

First that I tried to do is pass pointer to member to template parameter:

Property<&Holder::prop> prop;

or

Property<offsetof(Holder, prop)> prop;

But prop is not defined yet (it is error).

Full pseudocode will looks like this:

template<size_t FieldOffset>
class Property
{
    class Holder* GetOuter()
    {
           return (char*)this - FieldOffset;  // go to Outer object via offset of our field
    }
}

class Holder
{
    int Field1;
    std::string Field2;
    Property<offsetof(Holder, prop)> prop;  // Error!
}

Are there any other suggestions to do something similar?

like image 714
Artem Selivanov Avatar asked Mar 08 '26 13:03

Artem Selivanov


1 Answers

The memory model in C++ allows navigation from a member subobject to its containing (class-type) object only when the class is standard-layout and the member is the first member. The idea is that compilers can reason about which pointers have to escape for a write to necessitate reloading some other value from memory. As such, what you want is impossible in almost all cases, although there have been proposals to relax that rule so as to add features like this one.

like image 189
Davis Herring Avatar answered Mar 10 '26 03:03

Davis Herring



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!