【问题标题】:How can I properly reference the first vector container in my iterator?如何正确引用迭代器中的第一个向量容器?
【发布时间】:2018-06-10 23:48:02
【问题描述】:

现在,我正在尝试创建一个模板类 Set,它包含一个带有迭代器的泛型类型 <T>。虽然我不太明白目的是什么,但我应该为迭代器创建所谓的“结束哨兵”:

while(start != end)
   cout << start++ << endl;

startend 指的是我认为是向量的开始和结束。到目前为止,我已经创建了一个模板类,并在其中创建了一个迭代器。在我的主目录中,我插入 10 个整数,然后尝试使用我的“结束哨兵”。我的代码如下所示:

#include <iostream>
#include <vector>

using namespace std;

template <class T>
class Set{
     vector<T> theSet;
public:
    Set() {}
    Set(const Set& s): theSet(s.theSet){}
    ~Set(){theSet.clear();}

void insert(T t){
    cout << "inserted " << t << endl;
    theSet.push_back(t);
}

class iterator;
friend class iterator;
class iterator{
    Set<T>& s;
    int index;
public:
    iterator(Set<T>& is) : s(is), index(0) {}
    iterator(Set<T>& is, bool) : s(is) {}

   T operator*(){
        return s.theSet.at(index);          
   }

    T operator++(){
        return ++s.theSet.at(index);
    }
    T operator++(int){
        return s.theSet.at(index)++;
    }
    bool operator!=(const iterator& ri)const {return index!=ri.index;}
};

iterator begin() {return iterator (*this);}
//Create the end sentinel:
iterator end() {return iterator (*this, true); } 

};

int main()
{
    Set<int> other;

for(int i=0; i<10; ++i){
    other.insert(i);
}

/*
for(Set<int>::iterator start = other.begin(); start != other.end(); start++){
    cout << *start << endl;
}

cout << "\n\n Program ends succesfully" << endl;
*/

Set<int>::iterator start = other.begin();
Set<int>::iterator end = other.end();


while(start != end){
    cout << start++ << endl;
}
return 0;
}

当我在课堂结束时引用startend 时,问题就来了:

iterator begin() {return iterator (*this);}
//Create the end sentinel:
iterator end() {return iterator (*this, true); }

看来,begin() 使用第一个构造函数返回 iteratorend() 使用第二个构造函数返回 iterator,因为后者接受两个参数。然而,我得到的第二个构造函数看起来像

iterator(Set<T>& is, bool) : s(is) {}

我不确定这如何引用容器的“末端”。如何正确引用?

【问题讨论】:

  • 第二个 c'tor 实际上给 index 留下了一个不确定的值。这完全是错误的。
  • 好的,我想你在提到容器iterator(Set&lt;T&gt;&amp; is, bool) : s(is) {} 时是这个意思。我还是新手,我只是假设它只是构造函数。我将其更改为iterator(Set&lt;T&gt;&amp; is, bool) : s(is), index(9) {}。但是,我需要找到一种方法来始终引用最后一个元素。所以我想,我可以创建一个单独的int 来跟踪它?
  • 或者利用索引永远不会为负的事实。所以像-1 这样的东西可能是一个全局的“结束”。

标签: c++ vector iterator containers


【解决方案1】:

这里有一些示例代码。这仅用于演示目的!这段代码效率不高,并且缺少许多实际使用的功能!

#include <iostream>

using namespace std;

template <typename T>
class Set {
  int sz;
  T* elems;

 public:
  Set() : sz{0}, elems{nullptr} {}
  Set(int n) : sz{n}, elems{new T[n]} {}
  ~Set() { delete[] elems; }

  class Iterator;

  Iterator begin() { return Iterator{elems}; }
  Iterator end() {
    return Iterator{elems + sz};
  }  // points to past-the-end of elems
     // for example if sz=5:
     // 1 2 3 4 5 | 6
     // |           |
     // begin()    end()


  Iterator insert(T t) {
    // check if the element t exists in the set
    //    -> if so, then return the pointer to the existing element
    //    -> otherwise return the pointer to the newly inserted element
    // BUT:this is very inefficient !!!
    // in a real world code one would use
    // some kind of binary try for holding 
    // the keys/values of the set
    for (int i = 0; i < sz; i++)
      if (elems[i] == t)
        return Iterator{elems+i};

    T* new_elems = new T[sz + 1];
    for (int i = 0; i < sz; ++i)
      new_elems[i] = elems[i];

    new_elems[sz++] = t;
    delete[] elems;
    elems = new_elems;

    return Iterator{elems+sz};
  }

  class Iterator {
   public:
    Iterator() : p{nullptr} {}
    Iterator(T* pp) : p{pp} {}

    T* operator++() { return ++p; }  // pre-increment, ex. ++iter
    T* operator++(int) { return p++; } // post-increment, ex. iter++

    T& operator*() { return *p; }

    const T& operator*() const { return *p; }

    bool operator==(const Iterator& rhs) const { return p == rhs.p; }

    bool operator!=(const Iterator& rhs) const { return !this->operator==(rhs); }

   private:
    T* p;
  };  // Iterator

};    // Set

int main() {

  Set<int> s;
  s.insert(1);
  s.insert(2);
  s.insert(3);
  s.insert(4);

  for (Set<int>::Iterator it=s.begin(); it != s.end(); ++it)
    std::cout << *it << std::endl;
}

这是输出: https://wandbox.org/permlink/LT4F2CAkZhFCCcZw

【讨论】:

    猜你喜欢
    • 2021-12-20
    • 2017-08-29
    • 2011-04-24
    • 2017-12-29
    • 1970-01-01
    • 1970-01-01
    • 2018-12-15
    • 1970-01-01
    • 2012-01-15
    相关资源
    最近更新 更多