我有一个保存数据的链表,以及指向下一个节点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
。
是否可以在结构中放置运算符?我试过,并搜索了如何做,但因为我不处理运营商,我不知道该怎么做。
答案 0 :(得分: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 ¤t->data; }
T& operator * () const { return current->data; }
Node<T>* current;
};
请参阅std::slist<>
implementation以获取参考。看template<typename _Tp> struct _List_iterator
。阅读STL实施比许多书更好。
用法:
NodeIterator<T> it = &node;
++it;
T& t = *it;
答案 1 :(得分:4)
Node<T>& operator++(int) {…}
是您要实施的成员。
答案 2 :(得分:0)
要使代码生效,您需要能够为指针类定义operator++
。但这是不允许的。不过,欢迎您定义其他一些命名函数。例如:
template <typename Node>
Node goto_next(Node& node) {
Node result = node;
node = node->next;
return result;
}
然后你可以像这样使用它:
Node<int>* tmp = goto_next(someNode);
另一种选择是提供一个真正的迭代器类而不是仅使用指针:
Node<int>::iterator someNode = someList.begin();
Node<int>::iterator tmp = someNode++;
让你的迭代器保留一个Node<T>*
成员,并让++
运算符更新该内部指针,然后再返回迭代器对象的副本。
答案 3 :(得分:0)
你真的不想这样做。在指针上使用++
的想法非常接近于公共迭代器模式。你应该去全程,做一个真正的迭代器类。想想std::list<T>::iterator
。
Iterators是一个非常轻量级的包装器,它为节点指针提供了一个合理的接口,它提供了operator ++
之类的东西来移动到下一个节点,并重载operator ->
以提供对节点数据的简单访问。将客户端代码从使用指针转换为使用迭代器是非常简单的,因为语法几乎完全相同。