如何在迭代器中正确引用第一个向量容器?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在迭代器中正确引用第一个向量容器?相关的知识,希望对你有一定的参考价值。
现在,我正在尝试创建一个模板类Set
,它包含一个带有迭代器的泛型类型<T>
。虽然我不太明白目的是什么,但我仍然希望为迭代器创建一个所谓的“end sentinel”:
while(start != end)
cout << start++ << endl;
start
和end
指的是我认为是向量的开始和结束。到目前为止,我已经创建了一个模板类,在其中创建了一个迭代器。在我的主要内容中,我插入10个整数,然后尝试使用我的“end sentinel”。我的代码看起来像这样:
#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;
}
当我在课程结束时引用start
和end
时,问题出现了:
iterator begin() {return iterator (*this);}
//Create the end sentinel:
iterator end() {return iterator (*this, true); }
看来,begin()
用第一个构造函数返回iterator
,end()
用第二个构造函数返回iterator
,因为后者接受两个参数。但是,我得到的第二个构造函数看起来像
iterator(Set<T>& is, bool) : s(is) {}
我不确定这是如何引用容器的“结束”的。我怎样才能以正确的方式引用它?
答案
这里有一些示例代码。这仅用于演示目的!这段代码效率不高,现实世界中缺少很多功能!
#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
以上是关于如何在迭代器中正确引用第一个向量容器?的主要内容,如果未能解决你的问题,请参考以下文章
对于 C++ Random Access Iterator(向量迭代器),迭代器之间的差异是如何计算的?
如何仅使用 C++ 中的迭代器正确迭代 3D 向量? [关闭]