2

次のように、データを保存するリンクされたリストと、次のノードへのポインターがありますNode<T>* next

template <class T>
struct Node
{
    T data;
    Node<T>* next;
};

これにポストインクリメント演算子を入れたいので、ノードの前の値を返しますが、参照をインクリメントします。だから私はこれを行う場合

Node<int>* someNode = someList.SomeNode();
Node<int>* tmp = someNode++; 

tmpは元のsomeNode値になりますが、someNodeになりますsomeNode->next

構造体に演算子を入れることは可能ですか? 私はそれを試み、その方法を検索しましたが、オペレーターを扱っていないため、方法がわかりません。

4

4 に答える 4

6

ポインターのような基本型にメンバー関数を追加することはできません。

定義しようとしているのはイテレータです。成功するには、ノード ポインターに対してラッパー クラスを使用します。

template <class T>
struct NodeIterator
{
  NodeIterator(Node<T>* current) : current(current) {}
  NodeIterator& operator ++() { current = current->next; return *this; }
  NodeIterator operator ++(int) { 
      NodeIterator retVal = *this; 
      ++(*this);
      return retVal;
  }
  T* operator-> () const { return &current->data; }   
  T& operator * () const { return current->data; }   
  Node<T>* current;
};

参照については、std::slist<> 実装を参照してください。を見てくださいtemplate<typename _Tp> struct _List_iterator。STL 実装を読むことは、多くの本よりも優れています。

使用法:

NodeIterator<T> it =  &node;
++it;
T& t = *it;
于 2012-09-17T18:21:21.503 に答える
4
Node<T>& operator++(int) {…}

実装するメンバーです。

于 2012-09-17T17:45:54.337 に答える
0

operator++コードが機能するには、ポインター クラスを定義できる必要があります。しかし、それは許可されていません。ただし、他の名前付き関数を定義することは大歓迎です。例えば:

template <typename Node>
Node goto_next(Node& node) {
  Node result = node;
  node = node->next;
  return result;
}

次に、次のように使用できます。

Node<int>* tmp = goto_next(someNode);

もう 1 つのオプションは、ポインタを使用する代わりに実際のイテレータ クラスを提供することです。

Node<int>::iterator someNode = someList.begin();
Node<int>::iterator tmp = someNode++;

イテレーターにNode<T>*メンバーを保持させ、++オペレーターがイテレーター オブジェクトのコピーを返す前にその内部ポインターを更新するようにします。

于 2012-09-17T18:21:43.673 に答える
0

あなたは本当にそれをしたくありません。ポインターで使用するという考え方は++、一般的なイテレーター パターンに危険なほど近いものです。全力を尽くして、実際のイテレータ クラスを作成する必要があります。考えてみてくださいstd::list<T>::iterator

operator ++イテレータは、次のノードへの移動などを提供するノード ポインタへの適切なインターフェイスを提供する非常に軽量なラッパーでありoperator ->、ノード データへの簡単なアクセスを提供するオーバーロードです。構文がほとんど同じであるため、クライアント コードをポインターの使用からイテレーターの使用に変換するのは非常に簡単です。

于 2012-09-17T18:22:13.007 に答える