【问题标题】:Using `Node*` as iterator for a list使用 `Node*` 作为列表的迭代器
【发布时间】:2016-11-14 04:37:49
【问题描述】:
#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 一书中复制了这个重载。

谁能解释我做错了什么?

【问题讨论】:

    标签: c++ list c++11 iterator


    【解决方案1】:

    std::accumulate 的输入必须满足InputIterator 的要求。

    InputIterator 的要求之一是它支持预增量运算符。

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

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

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

    来自 C++11 标准(重点是我的):

    13.5 重载运算符

    6 操作符函数应为非静态成员函数或非成员函数,并且至少有一个类型为类、类引用、枚举或引用的参数到一个枚举

    【讨论】:

    • 但是我已经超载了Node*的预增量
    • 好的,您能解释一下 Stroustrup 先生是如何做到的吗?这是该书的链接。 dropbox.com/s/ipo5pkud6j4vr30/Straustrup4th.pdf?dl=0
    • @Ashot,本书使用double ad[] = {1,2,3,4}; double s1 = accumulate(ad,ad+4,0.0); double s2 = accumulate(ad,ad+4,0);。这些是完全有效的迭代器。
    • 页面顶部写着Node∗ operator++(Node∗ p) { return p−&gt;next; }。对吗?
    • @Ashot,我现在明白了。我很惊讶。这很可能是一个已在更高版本中更正的错误。
    【解决方案2】:

    您不能为原始类型或点重载运算符。所以你应该为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;
    };
    

    【讨论】:

      猜你喜欢
      • 2015-05-20
      • 2012-10-11
      • 1970-01-01
      • 1970-01-01
      • 2019-07-05
      • 1970-01-01
      • 2014-08-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多