2016-10-26 10 views
1

я наткнулся на этот код в последнее время, в контексте интрузивных списков:В чем смысл аргументов шаблона этого типа - `ClassA <T> T :: * ELEM`?

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. 
    .. 
    .. 
}; 

Я вижу подобный код в форсирования intrusive list library (member_hook<class T, class Hook, Hook T::* PtrToMember>).

Мой вопрос касается шаблона аргумента Node<T> T::*NODE. Я не эксперт в C++, но я никогда не сталкивался с этим конкретным синтаксисом раньше и не знаю, что искать, чтобы понять его.

Что это значит? Какова его цель и что я должен ее интерпретировать как «NODE является указателем на узел, принадлежащий T»? Это не имеет смысла для меня, потому что T, как известно, не содержит конкретных членов раньше времени, и, насколько я знаю, для разрешения области используется ::.

Кроме того, если кто-то может уточнить использование *NODE в этой строке, например: Node<T> *node = &(elem->*NODE);, это поможет мне понять, для чего это используется.

ответ

3

Это указатель участника. NODE является указателем на член T, который имеет тип Node<T>.

Аналогичным образом, foo->*bar является сокращением до (*foo).*bar где .* является оператором разыменования-указателя на оператор. elem->*NODE обращается к члену *elem, указанному NODE.

+0

Ожидается ли, что T будет иметь тип Node ? – aspen100

+1

@ aspen100 Да, это интрузивный бит. Чтобы использовать его как элемент «List',' T' должен содержать элемент «Node ». Местоположение этого элемента указывается указателем члена NODE. – melpomene

1

Это называется «указатель на оператор-член».

Стандарт (N3690, раздел 5.5) говорит:

указатель на член оператора -> * и * группа слева направо..

Бинарный оператор. * Связывает свой второй операнд, который должен иметь тип «указатель на член T» к его первому операнду, который должен быть класса T или класса, T которого является однозначной и доступной базой класс. Результат - это объект или функция типа, указанного вторым операндом.

Бинарный оператор -> * связывает свой второй операнд, который должен иметь тип «указатель на член Т» к его первому операнду, который должен иметь тип «указатель на Т» или «указатель на класс, из которого T - однозначный и доступный базовый класс ». Выражение E1 -> * E2 преобразуется в эквивалентную форму (* (E1)). * E2.

Также посмотрите на http://en.cppreference.com/w/cpp/language/operator_member_access.

Оператор :: * тот же - доступ с использованием имени класса вместо переменной, подобно тому, как у вас есть класс C и объект obj, вы можете либо выполнить C :: func, либо obj.func или (& obj) -> FUNC.

 Смежные вопросы

  • Нет связанных вопросов^_^