#include <iostream>
template <typename C, typename T>
std::ptrdiff_t offsetof_impl(T C::* ptr) {
C c; // only works for default constructible classes
T* t = &(c.*ptr);
return reinterpret_cast<char*>(&c) - reinterpret_cast<char*>(t);
}
template <typename C, typename T, T C::* Ptr>
std::ptrdiff_t offsetof() {
static std::ptrdiff_t const Offset = offsetof_impl(Ptr);
return Offset;
}
template <typename C, typename T, T C::* Ptr>
C& get_enclosing(T& t) {
return *reinterpret_cast<C*>(reinterpret_cast<char*>(&t) + offsetof<C, T, Ptr>());
}
// Demo
struct E { int i; int j; };
int main() {
E e = { 3, 4 };
E& ref = get_enclosing<E, int, &E::j>(e.j);
std::cout << (void const*)&e << " " << (void const*)&ref << "\n";
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGUgPHR5cGVuYW1lIEMsIHR5cGVuYW1lIFQ+CnN0ZDo6cHRyZGlmZl90IG9mZnNldG9mX2ltcGwoVCBDOjoqIHB0cikgewoJQyBjOyAvLyBvbmx5IHdvcmtzIGZvciBkZWZhdWx0IGNvbnN0cnVjdGlibGUgY2xhc3NlcwoJVCogdCA9ICYoYy4qcHRyKTsKCXJldHVybiByZWludGVycHJldF9jYXN0PGNoYXIqPigmYykgLSByZWludGVycHJldF9jYXN0PGNoYXIqPih0KTsKfQoKdGVtcGxhdGUgPHR5cGVuYW1lIEMsIHR5cGVuYW1lIFQsIFQgQzo6KiBQdHI+CnN0ZDo6cHRyZGlmZl90IG9mZnNldG9mKCkgewoJc3RhdGljIHN0ZDo6cHRyZGlmZl90IGNvbnN0IE9mZnNldCA9IG9mZnNldG9mX2ltcGwoUHRyKTsKCXJldHVybiBPZmZzZXQ7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBDLCB0eXBlbmFtZSBULCBUIEM6OiogUHRyPgpDJiBnZXRfZW5jbG9zaW5nKFQmIHQpIHsKCXJldHVybiAqcmVpbnRlcnByZXRfY2FzdDxDKj4ocmVpbnRlcnByZXRfY2FzdDxjaGFyKj4oJnQpICsgb2Zmc2V0b2Y8QywgVCwgUHRyPigpKTsKfQoKLy8gRGVtbwpzdHJ1Y3QgRSB7IGludCBpOyBpbnQgajsgfTsKCmludCBtYWluKCkgewoJRSBlID0geyAzLCA0IH07CglFJiByZWYgPSBnZXRfZW5jbG9zaW5nPEUsIGludCwgJkU6Omo+KGUuaik7CgkKCXN0ZDo6Y291dCA8PCAodm9pZCBjb25zdCopJmUgPDwgIiAiIDw8ICh2b2lkIGNvbnN0KikmcmVmIDw8ICJcbiI7CglyZXR1cm4gMDsKfQ==