[C/C++]_[初级]_[关于OutputIterator的简单介绍]

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/infoworld/article/details/80005893

场景

1.我们在使用算法库时, 免不了需要对集合进行排序, 复制, 移动等, 而对集合的元素进行操作就需要用到枚举(itereator).

2.我们一般是对已存在的集合进行遍历, 删除, 但是如果需要复制一个集合A内的元素到一个集合B内时如何操作, 这时候枚举怎么使用? 用枚举能很方便进行多元素添加, 而不需要使用效率低下的 for 循环.

说明

1.Iterator可以理解为一种可以对集合的元素进行标识和来回移动的类型, 也可以理解为一个抽象的指针. 它包括5 种类型的枚举: InputIterator, OutputIterator, ForwardIterator, BidirectionalIterator, 和 RandomAccessIterator; 如果是C++17 还包含一种类型 ContiguousIterator.

2.OutputIterator 是一种枚举, 它可以写入指向的元素. ForwardIterator, BidirectionalIterator, 或者 RandomAccessIterator 都是 OutputIterator的一种. OutputIterator 满足我们最常用的几种操作:

3.std::back_inserter 能快速的创建一个通过容器push_back函数添加元素的枚举, 当然容器要有push_back函数.

4.std::inserter 能快速的创建一个通过容器的insert函数添加元素的枚举, 当然容器要有insert函数, 没有编译报错.

*r = o // 这个比较特殊, r首先解引用后赋值, 之后r递增1, 指向下一个元素位置.
++r
r++
*r++ = o

例子

#include <assert.h>
#include <iostream>
#include <utility>
#include <iterator>
#include <set>
#include <typeinfO>

template <class A>
static void PrintArray(A& a)
{
  std::cout << typeid(a).name() << std::endl;
  if(a.begin() == a.end())
    return;

  auto ite = a.begin();
  std::cout << "(";
  std::cout << *ite;
  ite++;
  for(; ite != a.end();++ite){
    std::cout << "," << *ite;
  }
  std::cout << ")" << std::endl;
}

void TestIterator()
{
  std::vector<int> v;
  // back_insert_iterator 的用法, operator= 插入一个数据, 因为是back枚举, 每次都会调用
  // container的push_back函数.
  auto& itev = std::back_inserter(v);
  itev = 1;
  itev = 2;
  itev = 3;
  itev = 4;
  itev = 5;
  itev = 5;
  PrintArray(v);

  std::vector<int> f;
  f.push_back(-1);
  f.push_back(-2);
  f.push_back(-3);
  PrintArray(f);

  // 复制 v内的数组到f, 从f的第2个位置开始.
  std::copy(v.begin(),v.end(),std::inserter(f,std::next(f.begin())));
  PrintArray(f);

  // 复制vector到set, 过滤掉重复的.
  // std::inserter 每次都会调用容器的insert函数.
  std::set<int> s;
  std::copy(v.begin(), v.end(),std::inserter(s,s.begin())); 
  PrintArray(s);

  std::vector<int> result;
  std::sort(v.begin(),v.end());
  std::sort(f.begin(),f.end());

  // 获取两个集合的差集
  // 如果直接使用 result.begin()的话会崩溃, 
  // vector iterator not incrementable;
  // 因为 result.begin()不是OutputIterator, iterator不可以递增,result本身没有元素.
  //std::set_difference(f.begin(),f.end(),v.begin(),v.end(),result.begin());
  std::set_difference(f.begin(),f.end(),v.begin(),v.end(),std::back_inserter(result));
  PrintArray(result);
}

输出:

class std::vector<int,class std::allocator<int> >
(1,2,3,4,5,5)
class std::vector<int,class std::allocator<int> >
(-1,-2,-3)
class std::vector<int,class std::allocator<int> >
(-1,1,2,3,4,5,5,-2,-3)
class std::set<int,struct std::less<int>,class std::allocator<int> >
(1,2,3,4,5)
class std::vector<int,class std::allocator<int> >
(-3,-2,-1)

参考

OutputIterator
concept-Iterator
iterator
back_inserter
insert_iterator
inserter
next
copy

猜你喜欢

转载自blog.csdn.net/infoworld/article/details/80005893