C++ 迭代器分类

除了容器自定义的迭代器之外,标准库还提供了其他几种迭代器,包括插入迭代器,流迭代器,反向迭代器,移动迭代器。

插入迭代器

迭代器被绑定到一个容器上,可用来向容器插入元素。插入迭代器包括back_inserter, front_inserter, inserter三种。
back_inserter绑定到容器后,对该迭代器赋值,就执行了类似于push_back的操作,前提是该容器要支持push_back。
front_inserter绑定到容器后,对该迭代器赋值,就执行了类似于push_front的操作,前提是该容器支持push_front。
inserter创建一个使用insert的迭代器,此函数接受第二个参数必须是一个指向给定容器的迭代器,元素被插入到给定迭代器所表示的元素之前。

void use_inserter()
{
    list<int> list1 = {1, 2, 3, 4};
    list<int> list2, list3, list4;
    copy(list1.begin(), list1.end(), front_inserter(list2));
    copy(list1.begin(), list1.end(), back_inserter(list3));
    copy(list1.begin(), list1.end(), inserter(list4, list4.begin()));

    for_each(list2.begin(), list2.end(), [](const int &i)
             { cout << i << " "; });
    cout << endl;

    for_each(list3.begin(), list3.end(), [](const int &i)
             { cout << i << " "; });
    cout << endl;

    for_each(list4.begin(), list4.end(), [](const int &i)
             { cout << i << " "; });
    cout << endl;
}

程序输出

4 3 2 1
1 2 3 4
1 2 3 4

iostream迭代器

istream_iterator 读取输入流,ostream_iterator 向一个输出流写数据。
这些迭代器将它们对应的流当作一个特定类型的元素序列来处理。
通过使用流迭代器,我们可以用泛型算法从流对象读取数据以及向其写入数据。
我们先看看输入流的操作:

void use_istreamiter()
{
    //输入流迭代器
    istream_iterator<int> in_int(cin);
    //迭代器终止标记
    istream_iterator<int> in_eof;
    vector<int> in_vec;
    while (in_int != in_eof)
    {
        in_vec.push_back(*in_int++);
    }
    for_each(in_vec.begin(), in_vec.end(), [](const int &i)
             { cout << i << " "; });
    cout << endl;
}

上述代码创建了输入流迭代器in_int,绑定了cin。
同时生成了一个输入流的结尾迭代器in_eof,in_eof未绑定任何输入流,所以是输入流的终止。
通过循环将输入流数据写入in_vec中。
再看看输出流的操作:

void use_ostreamiter()
{
    vector<int> in_vec = {1, 3, 4, 2, 5, 6, 7, 9};
    ostream_iterator<int> out_in(cout, " ");
    for (auto data : in_vec)
    {
        *out_in++ = data;
    }
    cout << endl;
}

输出流迭代器out_in和cout绑定,并且为每一个输出的元素设置了空格间隔。
通过向*out_in赋值达到向cout写入数据的目的,同时out_in++保证了迭代器的后移。

反向迭代器

反向迭代器就是在容器中从尾元素向首元素反向移动的迭代器。对于反向迭代器,递增(以及递减)操作的含义会颠倒过来。递增一个反向迭代器(++it)会移动到前一个元素;递减一个迭代器(--it)会移动到下一个元素
cbegin和cend表示正向迭代器,crbegin和crend表示反向迭代器,如下图
https://www.ccppcoding.com/wp-content/uploads/16418855051.jpg
我们通过反向迭代器逆序打印原容器中的数据

void use_reverseiter()
{
    vector<int> in_vec = {1, 3, 4, 2, 5, 6, 7, 9};
    for (auto rit = in_vec.crbegin(); rit != in_vec.crend(); rit++)
    {
        cout << *rit << " ";
    }
    cout << endl;
}

程序输出9 7 6 5 2 4 3 1
我们知道sort默认规则是从小到大,如果我们想实现从大到小,可以利用反向迭代器完成

sort(vec.rbegin(), vec.rend());

反向迭代器遍历是从后往前,这一点也会造成一些不必要的问题

    string line = "FIRST,MIDDLE,LAST";
    auto rcomma = find(line.crbegin(), line.crend(), ',');
    cout << string(line.crbegin(), rcomma) << endl;

上述代码会找到最后一个逗号,获取crbegin和rcomma之间的数据实际是TSAL,也就是说反向迭代器遍历是反向的。
标准库提供了一个将反向迭代器转化为正向迭代器的方法base()

    //通过base将反向迭代器转化为正向的
    cout << string(rcomma.base(), line.cend()) << endl;

程序输出LAST
大家可以看一下正向迭代器和反向迭代器的关系图
https://www.ccppcoding.com/wp-content/uploads/1641887218.jpg

原文链接: https://www.cnblogs.com/secondtonone1/p/15788723.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    C++ 迭代器分类

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/184791

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月12日 上午10:48
下一篇 2023年2月12日 上午10:48

相关推荐