C++ Logo


Advanced search


From: Michael Scire <sciresm_at_[hidden]>
Date: Fri, 5 Nov 2021 16:09:14 -0700

I wanted to propose a utility for working with intrusive members at

Tentatively, I would propose

template<typename ParentType, typename MemberType> // Could we have
template<auto MemberPtr> with ParentType and MemberType deduced?
constexpr ParentType &parent_of_member(MemberType ParentType::*member_ptr,
MemberType &member) {
    if (std::is_constant_evaluated()) {
        // Compiler magic needed here
    } else {
        const uintptr_t member_address =
        const uintptr_t parent_address = member_address -

        return *reinterpret_cast<ParentType *>(parent_address);

Where parent_of_member would take in a pointer-to-member and a reference to
a member, and return a reference to the parent object if the reference
really is to the relevant member, and be undefined behavior otherwise.

The example run-time implementation above may not avoid undefined behavior,
but I do believe it is possible to implement without undefined behavior at
runtime. Please correct me if I'm wrong.

However, the reinterpret_casts/arithmetic above cannot be done at
compile-time, and so compiler-assistance would be necessary.

I think the above should be implementable -- both clang and gcc use
symbolic representations of objects at compile-time, and so the compiler
should have the ability to verify that the member reference is a member
reference in truth.

The above function is particularly useful for e.g. the case of intrusive
lists. My use case looks something like:

struct IntrusiveListNode {
    IntrusiveListNode *prev;
    IntrusiveListNode *next;

    // ...

class IntrusiveListImpl {
    // Common list management object for IntrusiveListNode, non-templated
and shared for all types using intrusive list nodes.
    // ...

template<class Traits>
class IntrusiveList {
    // Thin wrapper around IntrusiveListImpl for a specific intrusive list

template<auto MemberPtr, class Derived = /* Get ParentType from MemberPtr
class IntrusiveListMemberTraits;

template<class ParentType, IntrusiveListNode ParentType::*MemberPtr, class
class IntrusiveListMemberTraits<MemberPtr, Derived> {
        using ListType = IntrusiveList<IntrusiveListMemberTraits>;
        static constexpr IntrusiveListNode &GetNode(Derived &parent) {
            return parent.*MemberPtr;

        static constexpr IntrusiveListNode const &GetNode(Derived const
&parent) {
            return parent.*MemberPtr;

        static constexpr Derived &GetParent(IntrusiveListNode &node) {
            return static_cast<Derived &>(std::parent_of_member(MemberPtr,

        static constexpr Derived const &GetParent(IntrusiveListNode const
&node) {
            return static_cast<const Derived
&>(std::parent_of_member(MemberPtr, node));

struct ExampleTypeWithNode {
    int data;
    IntrusiveListNode node;

using ExampleTypeList =

At which point all works as expected, with ExampleTypeList being a list of
ExampleTypeWithNode using the member `node`.

I have all this implemented and working at run-time, with two primary
"Traits" variants -- one when node is a class member, and one where the
class derives from IntrusiveListBaseNode<T>.

When the intrusive node is a base of the class, GetParent/GetNode can be
implemented at compile-time (static_cast<Derived
&>(static_cast<IntrusiveListBaseNode<ParentType> &>(node))), and the code

It would be very useful to me to be able to have both variants of intrusive
list function at compile-time, instead of only one -- and there are other
intrusive members which would benefit greatly from this.

I also think that a standard-blessed way to use a pointer-to-member to go
from member to parent would be useful, rather than everybody using

My only thought is that it might be nice if the syntax could be e.g.
std::parent_of_member<MemberPtr>(member), rather than
std::parent_of_member(MemberPtr, member);


Received on 2021-11-05 18:09:30