c++templatesmember-pointersintrusive-containers

What is the meaning of template arguments of this type - `ClassA<T> T::*ELEM`?


I came across this code recently, in the context of intrusive lists:

template<typename T> struct Node{
    T *next;
    T *prev;
    Node(): next(nullptr), prev(nullptr){}
};


/*
 * Intrusive doubly-linked-list
 *
 * */
template<typename T, Node<T> T::*NODE>
class List{
T *head;
T *tail;
public: 
    List():head(nullptr), tail(nullptr){}
    ~List() {clear();}

    /*
    * Add an element at the head of list
    * @param elem item to be inserted
    * */
    void add_to_front(T *elem){

        Node<T> *node = &(elem->*NODE);

        assert((node->next) == nullptr);
        assert((node->prev) == nullptr);

        node->next = head;

        if(head != nullptr){
            Node<T> *temp = &(head->*NODE);
            temp->prev = elem;
        }

        head = elem;

        if(tail == nullptr)
            tail = head;

    }
    //other member functions ,etc.
    ..
    ..
};

I see similar code in the boost intrusive list library (member_hook<class T, class Hook, Hook T::* PtrToMember>).

My question is regarding the template argument Node<T> T::*NODE. I am not an expert in C++, but I have never come across this particular syntax before, and don't know what to search for to understand it.

What does it mean? What is its purpose, and what should I interpret it as - "NODE is a pointer to a Node, belonging to T"? That doesn't make sense to me, because T isn't known to contain specific members ahead of time, and as far as I know, :: is used to resolve scope.

As well, if someone could clarify the use of *NODE in this line, for instance : Node<T> *node = &(elem->*NODE);, that would help me understand what this is being used for.


Solution

  • It's a member pointer. NODE is a pointer to a member of T that has type Node<T>.

    Similarly, foo->*bar is shorthand for (*foo).*bar where .* is the dereference-pointer-to-member operator. elem->*NODE accesses the member of *elem pointed to by NODE.