[c++] Iterators

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

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

需要躲过的坑,野指针。

 

性能预览

一、基本性质

访问方式

 

遍历数据

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

int main()
{
    cout << "Hello World!" << endl;

    vector<int> v = {1, 2, 3, 4, 5};
    int i = 10;

// 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 0; }

 

二、Iterator的层级关系 

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

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

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

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

       

  

三、基本操作

 

四、避免野 Iterator

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

要么删除的同时返回next.

  • 解决方法一

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

// 注意p2的使用

i = 0; 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 = 0; 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{1, 2, 3, 4, 5};
    ostream_iterator<int> os(cout, ",");
for (const auto &i: v) { *os++ = i; } }

 

 End.

posted @ 2016-12-02 07:33  郝壹贰叁  阅读(310)  评论(0编辑  收藏  举报