【问题标题】:Overloading the ++ operator to increment an iterator重载 ++ 运算符以增加迭代器
【发布时间】:2012-03-12 06:39:24
【问题描述】:

我目前正在创建一个方形列表,其中一个要求是重载前置和后缀 ++ 运算符。

我尝试在我的 .hpp 文件中重载 ++ 运算符以递增迭代器。但是在调用 ++ 运算符时,它不会调用重载的代码,而只是使用默认值。

iterator& operator ++ () {  // pre-increment 
        std::list<int>::iterator i = list_Values.begin(); 
        advance(i,1); 
        return &*i; 
    } 

    iterator operator ++ (int) { // post-increment 
        std::list<int>::iterator i = list_Values.begin(); 
        advance(i,1); 
        return &*i; 
    } 

我尝试以这种方式调用 ++ 运算符:

int* test = sqrList.begin();
  ++test;

  test++;

【问题讨论】:

  • 默认?没有默认operator++
  • @Pubby 很好,当我逐步完成它进入标准库时
  • 为什么要在容器上定义 ++?在迭代器类型上做,当然,但不是容器......
  • 看起来 ++ 应用于 any 迭代器总是给你一个过去的开头,对吗?
  • 您的代码有问题。 非常错误。当期望迭代器作为返回类型时,您将返回一个指向某物的指针,您正在返回对预增量中的局部变量的引用,并且容器类中似乎有 operator++

标签: c++ visual-studio-2010 iterator operators operator-overloading


【解决方案1】:

对于新手来说,有时很难脱离上下文理解问题。所以我决定提供一个或多或少完整的例子来定义自定义迭代器和重载它的操作符。 请注意,当重载后自增运算符时,我们按值返回迭代器,而不是按引用返回。 当然,这不是一个真实的例子,我们不会使用原始指针。

#include<iostream>
#include<assert.h>

struct node
{
    int data;
    node* next;
    node() :data(0), next(nullptr) {}
    node(int d) :data(d), next(nullptr) {}
};

//forward declaration
class MyList;

class MyListIterator
{
private:
    node* _ptr;
    friend class MyList;
    explicit MyListIterator(node* n) : _ptr(n) {}
public:
    int& operator*() const {
        return _ptr->data;
    }
    //overload pre increment operator
    MyListIterator& operator++() {
        _ptr = _ptr->next;
        return *this;
    }
    // overload post increment operator
    MyListIterator operator++(int) {
        MyListIterator ret = *this;
        ++* (this);
        return ret;
    }

    bool operator==(const MyListIterator& iter) const {
        return this->_ptr == iter._ptr;
    }

    bool operator!=(const MyListIterator& iter) const {
        return this->_ptr != iter._ptr;
    }
};

class MyList
{
private:
    node* _head;
    node* _tail;
    size_t _size;
public:
    MyList() : _head(nullptr), _tail(nullptr), _size(0) {};

    void push_back(int d) {
        node* newTail = new node(d);
        if (_tail != nullptr) {
            _tail->next = newTail;
        }
        else {
            _head = newTail;
        }
        _tail = newTail;
        _size++;
    }

    int& operator[](size_t i) {
        if (i >= _size)
            throw std::out_of_range("MyList");
        node * p = _head;
        for (size_t j = 0; j < i; j++) {
            p = p->next;
        }
        return p->data;
    }

void remove(int d) {
    if (_head == nullptr)
        return;
    node * p = _head;
    node * prev = p;
    while ((p != nullptr) && (p->data != d)) {
        prev = p;
        p = p->next;
    }
    if (p != nullptr) {
        if (p == _head)
            _head = p->next;
        else
            prev->next = p->next;
        delete p;
        _size--;
    }
}

    size_t size() const {
        return _size;
    }

    ~MyList() {
        node* next = nullptr;
        for (node* p = _head; p != nullptr; p = next) {
            next = p->next;
            delete p;
        }
    }
    using iterator = MyListIterator;
    iterator begin() { return iterator(_head); }
    iterator end() { return iterator(_tail->next); }
};

int main()
{

    MyList mylist;
    mylist.push_back(1);
    mylist.push_back(2);
    mylist.push_back(3);
    int count = 1;
    //pre increment
    for (MyListIterator it = mylist.begin(); it != mylist.end(); ++it)
        assert(*it == count++);
    count = 1;
    //post increment
    for (MyListIterator it = mylist.begin(); it != mylist.end(); it++)
        assert(*it == count++);
    for (size_t i = 0; i < 3; i++)
        assert(mylist[i] == i + 1);

    mylist.remove(2);
    assert(mylist[0] == 1);
    assert(mylist[1] == 3);
    assert(mylist.size() ==2);

    mylist.remove(1);
    mylist.remove(3);
    assert(mylist.size() == 0);

}

【讨论】:

    【解决方案2】:
    int* test = sqrList.begin();
    ++test;
    test++;
    

    您正在递增 int*,并且由于没有要扩展的 int* 类,您不可能实际上为这种类型创建运算符。

    改为为正确的类型创建运算符。您可能打算创建自己的 Iterator 类型。

    【讨论】:

      【解决方案3】:

      你必须在类中声明操作符。

      class Iterator
      {
      public:
          Iterator& operator ++ ()
          {
             return *this;
          }
          Iterator operator ++ (int)
          {
             return *this;
          }
      };
      

      另外,你为什么用return &amp;*i;

      请注意,这些运算符需要在 Iterator 类中声明,而不是在容器中。

      【讨论】:

      • 我已经试过了,它似乎仍然没有进入我的重载函数
      • 投反对票的不是我。无论如何,我认为这是我需要做的......我会试一试并发表评论
      猜你喜欢
      • 1970-01-01
      • 2011-10-18
      • 2020-06-14
      • 1970-01-01
      • 1970-01-01
      • 2011-12-07
      • 2013-09-07
      • 2017-02-22
      • 2011-05-18
      相关资源
      最近更新 更多