迭代器适配器(一)back_inserter和front_inserter的实现
本文讨论back_inserter和front_inserter的实现。
当我们调用copy函数的时候,要确保目标容器具有足够大的空间,例如:
//将other的所有元素拷贝到以coll.begin()为起始地址的位置
copy(other.begin(), other.end(), coll.begin());
如果之前没有为coll分配好内存,那么会引发越界错误。
如果我们无法提前预分配内存,那么怎么办?我们可以使用如下的代码:
//将other的所有元素拷贝到以coll.begin()为起始地址的位置
copy(other.begin(), other.end(), back_inserter(coll.begin()));
我们用了一个东西叫做back_inserter,它是一种插入迭代器(后面你会看到,它实际是个函数),那么插入迭代器是什么?
我们知道,迭代器用来实现容器操作的一种抽象,有了迭代器,那么我们遍历所有容器,采用的几乎都是同一种方式,换句话说,迭代器帮我们屏蔽了容器操作的细节。
对于元素的插入,不同的容器有不同的操作,例如push_back、insert等,插入迭代器就是帮我们屏蔽插入元素的细节,使得iter看起来总是指向一个“可用的位置”。
back_inserter的使用如下:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std; template <typename T>
void printElems(const T &t, const string &s = "")
{
cout << s << " ";
for(typename T::const_iterator it = t.begin();
it != t.end();
++it)
{
cout << *it << " ";
}
cout << endl;
} int main(int argc, char const *argv[])
{
vector<int> coll;
back_insert_iterator<vector<int> > iter(coll);
*iter = ;
iter++;
*iter = ;
++iter;
*iter = ;
printElems(coll); back_inserter(coll) = ;
back_inserter(coll) = ; printElems(coll); copy(coll.begin(), coll.end(), back_inserter(coll));
printElems(coll); return ;
}
可以看出,插入迭代器的使用很简易,而且不需要我们考虑内存的分配,因为迭代器内部帮我们处理了这些细节。正如前面所说,插入迭代器总是指向一块可用的位置,我们很快即将看到它的细节实现。
需要注意一下几点:
1.插入迭代器本质上是一种适配器,但是它看起来像一个迭代器,行为像一个迭代器,那么他就符合迭代器的定义。
2.插入迭代器的赋值,内部采用了插入元素的做法,可能调用容器的push_back push_front或者insert等。
3.插入迭代器的++操作,只是个幌子,但必不可少。以上面的copy为例,内部肯定调用了iter++,因为copy函数只是把它当做普通迭代器。
4.解引用操作同样也是幌子。
back_inserter和front_inserter实现代码如下
#ifndef ITERATOR_HPP
#define ITERATOR_HPP template <typename Container>
class BackInsertIterator
{
public:
typedef typename Container::value_type value_type; explicit BackInsertIterator(Container &cont) :cont_(cont) { } BackInsertIterator<Container> &operator=(const value_type &val)
{
cont_.insert(cont_.end(), val);
return *this;
} BackInsertIterator<Container> &operator*()
{
return *this;
} BackInsertIterator<Container> &operator++()
{
return *this;
}
//iter++没有实质操作,所以也是返回引用
BackInsertIterator<Container> &operator++(int)
{
return *this;
} private:
Container &cont_;
}; template <typename Container>
BackInsertIterator<Container> backInserter(Container &c)
{
return BackInsertIterator<Container>(c);
} //FrontInsertIterator
template <typename Container>
class FrontInsertIterator
{
public:
typedef typename Container::value_type value_type; explicit FrontInsertIterator(Container &cont) :cont_(cont) { } FrontInsertIterator<Container> &operator=(const value_type &val)
{
cont_.insert(cont_.begin(), val);
return *this;
} FrontInsertIterator<Container> &operator*()
{
return *this;
} FrontInsertIterator<Container> &operator++()
{
return *this;
}
FrontInsertIterator<Container> &operator++(int)
{
return *this;
} private:
Container &cont_;
}; template <typename Container>
FrontInsertIterator<Container> frontInserter(Container &c)
{
return FrontInsertIterator<Container>(c);
}
#endif //ITERATOR_HPP
从上面的源码我们可以看到,二者插入均采用的insert操作。当然,调用push_back和push_front也是可以的。
迭代器适配器(一)back_inserter和front_inserter的实现的更多相关文章
- STL之--插入迭代器(back_inserter,inserter,front_inserter的区别)
除了普通迭代器,C++标准模板库还定义了几种特殊的迭代器,分别是插入迭代器.流迭代器.反向迭代器和移动迭代器,定义在<iterator>头文件中,下面主要介绍三种插入迭代器(back_in ...
- function adapter(函数适配器)和迭代器适配器
所谓function adapter(函数适配器)是指能够将不同的函数对象(或是和某值或某寻常函数)结合起来的东西,它自身也是个函数对象. 迭代器适配器 运用STL中的迭代器适配器,可以使得算法能够 ...
- 迭代器适配器{(插入迭代器back_insert_iterator)、IO流迭代器(istream_iterator、ostream_iterator)}
一.迭代器适配器 反向迭代器 插入迭代器 IO流迭代器 其中反向迭代器可以参考以前的文章. 二.插入迭代器 插入迭代器实际上是一个输出迭代器(*it=; ++) back_insert_iterato ...
- 【C++ STL应用与实现】18: 怎样使用迭代器适配器
本系列文章的文件夹在这里:文件夹. 通过文件夹里能够对STL整体有个大概了解 前言 本文介绍了STL中的迭代器适配器(iterator adapter)的概念及其用法演示样例.迭代器适配器能够和标准库 ...
- STL 迭代器适配器(iterator adapter)
iterator adapter graph LR iterator --- reverse_iterator iterator --- Insert_iterator iterator --- io ...
- 迭代器适配器(二)general inserter的实现
上节我们实现了back_inserter和front_inserter,接下来是更为普通的插入迭代器,它允许用户指定插入位置. 实现代码如下: #ifndef ITERATOR_HPP #define ...
- STL标准库-迭代器适配器
技术在于交流.沟通,本文为博主原创文章转载请注明出处并保持作品的完整性 这次主要介绍一下迭代器适配器.以reverse_iterator(反向迭代器),insert_iterator(插入迭代器),o ...
- STL适配器的初步理解
c++中的适配器有三种:容器适配器,迭代器适配器,函数适配器.下面一一介绍: 1.容器适配器:因为这些容器都是基于其他标准容器实现的所以叫做容器的适配器,具体的有stack,queue,priorit ...
- 【C++】C++中的迭代器
目录结构: contents structure [-] 迭代器运算符 迭代器类型 begin和end运算符 迭代器的算术运算 可以使用下标来访问string对象或vector对象的元素,还有另外一种 ...
随机推荐
- linux低权限执行高权限
1.关于sudo不需要输密码,低权限执行高权限,在root下的命令visudo放开%wheel ALL:保存退出, 执行gpasswd -a yourusername wheel 2.脚本命令下的,权 ...
- 百度之星复赛T6&&hd6149 ——Valley Numer II
Problem Description 众所周知,度度熊非常喜欢图. 它最近发现了图中也是可以出现 valley —— 山谷的,像下面这张图. 为了形成山谷,首先要将一个图的顶点标记为高点或者低点.标 ...
- 创建型设计模式之原型模式(Prototype)
结构 意图 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 适用性 当要实例化的类是在运行时刻指定时,例如,通过动态装载:或者 为了避免创建一个与产品类层次平行的工厂类层次时:或 ...
- Git 新项目关联到远程仓库
最近前端学到小有成果,准备写一个新项目放在githup,结果没有提前在仓库创建项目,现在我把写好的项目推送到远程gitHup 1.先初始化本地仓库 Git init : 这样在项目里面都创建了一个隐藏 ...
- windows安装scrapy
1.安装Twisted 直接pip install Twisted 然后报错 error: Microsoft Visual C++ 14.0 is required. Get it with &qu ...
- python--bs4
- python--websocket数据解析
# websocket实现原理 ''' 1.服务端开启socket,监听ip和端口 2.客户端发送连接请求(带上ip和端口) 3.服务端允许连接 4.客户端生成一个随机字符串,和magic strin ...
- python--线程池(concurrent.futures)
#!/usr/bin/env python # -*- coding:utf-8 -*- # author:love_cat # 为什么需要线程池 # 1.主线程中可以获取某一个线程的状态或者某一个任 ...
- 关于多态的理解,有助于理解TStream抽象类的多态机制。
有的时候 不是很明白流的机制,因为有内存流 文件流 图片流 等等 他们之间的相互转化 靠的就是流的多态性.... unit Unit11; interface uses Winapi.Windows ...
- mysql运维必会的一些知识点整理(转自民工哥)
(1)基础笔试命令考察 1.开启MySQL服务 /etc/init.d/mysqld start service mysqld start systemctl start mysqld 2.检测端口是 ...