1

最近、侵入リストのコンテキストでこのコードに出くわしました。

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

ブースト侵入型リスト ライブラリ( member_hook<class T, class Hook, Hook T::* PtrToMember>) にも同様のコードがあります。

私の質問は、テンプレート引数に関するものNode<T> T::*NODEです。私は C++ の専門家ではありませんが、この特定の構文にこれまで出会ったことがなく、理解するために何を検索すればよいかわかりません。

どういう意味ですか?その目的は何ですか?「NODE は T に属するノードへのポインタです」と解釈する必要がありますか? T には事前に特定のメンバーが含まれていることがわかっておらず、私の知る限り、::スコープを解決するために使用されるため、これは私には意味がありません。

同様に、誰かが*NODEこの行での使用を明確にすることができれば、たとえば : Node<T> *node = &(elem->*NODE);、これが何のために使用されているかを理解するのに役立ちます.

4

2 に答える 2

3

メンバーポインタです。型を持つNODEのメンバへのポインタです。TNode<T>

同様に、 is はwhere is dereference-pointer-to-member 演算子のfoo->*bar省略形です。が指すのメンバーにアクセスします。(*foo).*bar.*elem->*NODE*elemNODE

于 2016-10-26T20:33:45.227 に答える
1

これは「メンバー演算子へのポインター」と呼ばれます。

標準 (N3690、セクション 5.5) は次のように述べています。

メンバーへのポインター演算子 ->* および .* は、左から右にグループ化されます。

二項演算子 .* は、「T のメンバへのポインタ」型である 2 番目のオペランドを、クラス T または T が明確でアクセス可能な基底クラスであるクラスである最初のオペランドにバインドします。結果は、2 番目のオペランドで指定された型のオブジェクトまたは関数です。

二項演算子 ->* は、「T のメンバーへのポインター」型である 2 番目のオペランドを、「T へのポインター」または「T が明確なクラスへのポインター」型である最初のオペランドにバインドします。アクセス可能な基本クラスです。」式 E1->*E2 は、同等の形式 (*(E1)).*E2 に変換されます。

http://en.cppreference.com/w/cpp/language/operator_member_accessもご覧ください。

演算子 ::* も同じです -- 変数の代わりにクラス名を使用してアクセスします。クラス C とオブジェクト obj がある場合、C::func または obj.func または (&obj)->func のいずれかを実行できます。

于 2016-10-26T20:35:36.560 に答える