[c++] Iterators

迭代器(Iterator)是指针(pointer)的泛化,它允许程序员用相同的方式处理不同的数据结构(容器)

性质 depends on various containers,因为其实现就是不同的容器实现各自的迭代器.

需要躲过的坑,野指针。

性能预览

一、基本性质

访问方式

[c++] Iterators

遍历数据

container返回的位置实际上就是智能指针,使用auto就不用罗里吧嗦地写那个长长的 typename。

int main()
{
cout << "Hello World!" << endl; vector<int> v = {, , , , };
int i = ; // If const Containers: v.cbegin(), v.cend()
for (auto p = v.begin(); p != v.end(); p++)
{
i++;
(*p) = i;
cout << (*p) << endl;
}
// 正遍历
/*******************************************/
// 反遍历
for (auto p = v.rbegin(); p != v.rend(); p++)
{
cout << (*p) << endl;
} return ;
}

二、Iterator的层级关系

所讨论到的几个迭代器的层次.看起来很像继承是麽?但其实"不是".

但是实际上在STL中,这些并不是通过继承关联的.这些只不过是一些符合条件的集合.

这样的好处是:少去了一个特殊的基类(input iterator);其次,使得内建类型指针可以成为 iterator.

其实只要明白iterator是满足某些特别的功能的集合(包括类和内建类型),就不会觉得是继承了.

[c++] Iterators

三、基本操作

[c++] Iterators

四、避免野 Iterator

要么提前deep copy指针的相关信息,方便之后next.

要么删除的同时返回next.

  • 解决方法一

就是ease后对iter进行重新赋值。

// 注意p2的使用

i = ;
vector<int>::iterator p = v.begin();
vector<int>::iterator p2;
for (; p != v.end(); p++)
{
cout << "i = " << i++ << ", " << (*p) << endl;
p2 = p;
v.erase(p2);
}
  • 解决方法二

再使用一个迭代器

// erase之后自动++;不erase则需++

i = ;
vector<int>::iterator p = v.begin();
for (; p != v.end();)
{
cout << "i = " << i++ << ", " << (*p) << endl;
p = v.erase(p);
}

Iterator(迭代器)分类

Ref: c++ iterator(迭代器)分类及其使用

一、迭代的个性化需求

在find中,我们要求P必须允许 != ,++和*(P)这三个运算符的操作.

iterator实现上通过struct,然后去实现运算符重载.

template<class P, class T>
P find(P start, P beyond, const T& x)
{
while( start != beyond && * start != x)
++start;
return start;
}

二、迭代器的使用

istream_iterator

  • 读取输入流
    ifstream in("data.in");
std::istream_iterator<int> begin(in);
std::istream_iterator<int> end; // read the first int
cout << *begin++ << endl; //skip the 2nd int
++begin; // read the 3rd int
cout << *begin++ << endl; while (begin != end)
{
cout << *begin++ << endl;
}
  • 插入到容器尾部

back_insert_iterator,顾名思义是个迭代器(后缀iterator),是一个模板类。

    ifstream in("data.in");
std::istream_iterator<int> begin(in);
std::istream_iterator<int> end; vector<int> v; back_insert_iterator<vector<int>> iter(v); while (begin != end)  // 默认读到 EOF
{
*iter++ = *begin++;
} cout << "------------------------------\n";
for (auto p = v.begin(); p != v.end(); p++)
{
cout << (*p) << endl;
}

std::back_inserter(v):是一个模板函数,实现在容器尾部插入元素。

    vector<string> v;

    ifstream in("data.in");
std::copy(istream_iterator<string>(in),
istream_iterator<string>(),  // 默认读到 EOF
std::back_inserter(v) );

ostream_iterator

void func_ostream()
{
vector<int> v{, , , , };
ostream_iterator<int> os(cout, ",");
for (const auto &i: v)
{
*os++ = i;
}
}

End.

上一篇:1 实现添加功能 1.1 定义一个学员类(Student),在Student类中定义姓名、性别和年龄属性,定义有 参数的构造方法来初始化所以的成员属性 1.2 创建学员类对象来存放学员信息,并且为每一个学生对象添加的相应的编号。并将 学员类对象添加到Map集合中 1.3 添加完成后,显示所有已添加的学员姓名 1.4 限制年龄文本框只能输入正整数,否则的会采


下一篇:原型链、prototype、_proto_那些事