使用“Node*”作为列表的迭代器

Using `Node*` as iterator for a list

本文关键字:列表 迭代器 Node 使用      更新时间:2023-10-16
#include <iostream>
#include <algorithm>
struct Node
{
    int value_;
    Node* next_;
    Node(int value, Node* next = nullptr)
        : value_(value)
        , next_(next)
    {}
};
Node* operator++(Node* node)
{
    node = node->next_;
    return node;
}
int operator*(Node* node)
{
    return node->value_;
}
int main()
{
    Node* first = new Node(10);
    first->next_ = new Node(20);
    first->next_->next_ = new Node(17);
    Node* endIter = nullptr;
    std::cout << std::accumulate(first, endIter, 0) << std::endl;
}

在此示例中,我尝试使用 Node* 作为列表的迭代器。我收到编译器错误

  1 main.cpp:15:28: error: Node* operator++(Node*) must have an argument of class or enumerated type
  2  Node* operator++(Node* node)
  3                             ^
  4 main.cpp:21:25: error: int operator*(Node*) must have an argument of class or enumerated type
  5  int operator*(Node* node)

看起来我不能超载operator++operator*指针。

我已经从书中复制了这个重载 Stroustrup: The C++ Programming Language (4th Edition) pg 703.

谁能解释我做错了什么?

std::accumulate的输入必须满足输入迭代器的要求。

输入迭代器的要求之一是它支持预递增运算符。

您可以在Node*上使用预递增运算符,但它将使用内置逻辑来递增指针。

Node* operator++(Node* node) { ... }

无效,因为参数的类型是 Node* 。您可以重载operator++ Node,但不能重载Node*

来自 C++11 标准(强调我的):

13.5 重载运算符

6 运算符函数可以是非静态成员函数,

也可以是非成员函数,并且至少有一个参数的类型是类、对类的引用、枚举或对枚举的引用

不能重载基元类型或点的运算符。所以你应该为Node编写一个迭代器。

class iterator {
public:
  iterator(Node *node): _node(node) {}
  iterator operator++() {
    _node = _node->next;
    return *this;
  }
  iterator operator++(int) {
    iterator tmp = *this;
    ++(*this);
    return tmp;
  }
  bool operator == (const iterator &iter) const {
    return _node == iter._node;
  }
  int operator*() {
    return _node->value;
  }
private:
  Node *_node;
};