template<typename Iterator> class move_iterator
{
Iterator current;
public:
typedef Iterator iterator_type;
typedef typename std::iterator_traits<Iterator>::iterator_category iterator_category;
typedef typename std::iterator_traits<Iterator>::value_type value_type;
typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
typedef Iterator pointer; typedef value_type&& reference; move_iterator(){}
explicit move_iterator(Iterator it):current(it){}
template<typename Iter> move_iterator(const move_iterator<Iter>& it):current(it.current){}
template<typename Iter> move_iterator& operator=(const move_iterator<Iter>&it)
{
current = it.current;
}
iterator_type base() const{ return current;}
pointer operator->()const{return current;} reference operator*()const{return std::move(*current);} move_iterator&operator++(){++current; return *this;}
move_iterator&operator--(){--current; return *this;} move_iterator&operator++(int){move_iterator temp = *this; ++current; return temp;}
move_iterator&operator--(int){move_iterator temp = *this; --current; return temp;} move_iterator operator+(difference_type n) const {return move_iterator(current + n);}
move_iterator operator-(difference_type n) const {return move_iterator(current - n);}
move_iterator operator+=(difference_type n) {current += n; return *this;}
move_iterator operator-=(difference_type n) {current -= n; return *this;} auto operator[](difference_type n) const -> decltype(std::move(current[n]))
{
return std::move(current[n]);
} };

从实现上可以看出,基本是普通Iterator加了外包装。

其中特别值得注意的几个点:

typedef value_type&& reference;

auto operator[](difference_type n) const -> decltype(std::move(current[n]))
{
return std::move(current[n]);
} reference operator*()const{return std::move(*current);}

可以发现,这种迭代器呈现出差别就在解引用的时候强制转换成右值引用,这样就可以实现从一个容器中”移走“所有的元素


#include<vector>
#include<algorithm>
#include<stack>
#include<iostream>
#include<string>
using namespace std; int main()
{
std::vector<std::string> foo();
std::vector<std::string> bar{"one", "two", "three"}; typedef std::vector<std::string>::iterator Iter; std::copy(std::move_iterator<Iter>(bar.begin()),
std::move_iterator<Iter>(bar.end()), foo.begin()); bar.clear();
std::cout << "foo:";
for(std::string& x : foo) cout << ' ' << x;
std::cout << '\n';
return ;
}

对于这个程序,可以跟踪一下,发现最后bar在copy之后,虽然仍旧含有三个元素,但都变成了"",可见已经被“掏空”了

后面那个clear只是使得bar的size减到0而已,可谓多此一举。

所有的差别,不过是因为我们输入参数用move_iterator裹了一层:std::move_iterator<Iter>(bar.begin())

还有就是move_iterator是模板类,不是模板函数,所以需要显式写出模板参数,在这里就显得有些啰嗦了。

还可以看一下另一个关于解引用的例子

#include<iterator>
#include<string>
#include<iostream>
#include<vector>
using namespace std;
int main()
{
std::string str[] = {"one", "two", "three"};
std::vector<std::string> foo; std::move_iterator<std::string*> it(str);
for(int i = ; i < ; i++)
{
foo.push_back(*it);
++it;
}
std::cout << "foo:";
for(std::string& x : foo) std::cout << " " << x;
std::cout << "\n";
return ;
}

因为普通指针也可以被iterator_traits识别为迭代器,所以也可以用move_iterator进行包装

C++11 move_iterator的更多相关文章

  1. 地区sql

    /*Navicat MySQL Data Transfer Source Server : localhostSource Server Version : 50136Source Host : lo ...

  2. C++11 std::copy

    这个函数并不是简单的 while(first != last) { *result = *first; result++; first++; } 事实上这种写法是最具普适性的,值要求inputIter ...

  3. WinForm 天猫2013双11自动抢红包【源码下载】

    1. 正确获取红包流程 2. 软件介绍 2.1 效果图: 2.2 功能介绍 2.2.1 账号登录 页面开始时,会载入这个网站:https://login.taobao.com/member/login ...

  4. C++11特性——变量部分(using类型别名、constexpr常量表达式、auto类型推断、nullptr空指针等)

    #include <iostream> using namespace std; int main() { using cullptr = const unsigned long long ...

  5. CSS垂直居中的11种实现方式

    今天是邓呆呆球衣退役的日子,在这个颇具纪念意义的日子里我写下自己的第一篇博客,还望前辈们多多提携,多多指教! 接下来,就进入正文,来说说关于垂直居中的事.(以下这11种垂直居中的实现方式均为笔者在日常 ...

  6. C++ 11 多线程--线程管理

    说到多线程编程,那么就不得不提并行和并发,多线程是实现并发(并行)的一种手段.并行是指两个或多个独立的操作同时进行.注意这里是同时进行,区别于并发,在一个时间段内执行多个操作.在单核时代,多个线程是并 ...

  7. CSharpGL(11)用C#直接编写GLSL程序

    CSharpGL(11)用C#直接编写GLSL程序 +BIT祝威+悄悄在此留下版了个权的信息说: 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharp ...

  8. ABP(现代ASP.NET样板开发框架)系列之11、ABP领域层——仓储(Repositories)

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之11.ABP领域层——仓储(Repositories) ABP是“ASP.NET Boilerplate Proj ...

  9. C++11 shared_ptr 智能指针 的使用,避免内存泄露

    多线程程序经常会遇到在某个线程A创建了一个对象,这个对象需要在线程B使用, 在没有shared_ptr时,因为线程A,B结束时间不确定,即在A或B线程先释放这个对象都有可能造成另一个线程崩溃, 所以为 ...

随机推荐

  1. AC自动机 & Fail树 专题练习

    Fail树就是AC自动机建出来的Fail指针构成的树. [bzoj3172][xsy1713]单词 题意 给定一些单词,求每个单词在所有单词里面的出现次数. 分析 构建Fail树,记录每个单词最后一个 ...

  2. 【CITE】DrawImage方法详解(转)

    Image和Bitmap类概述 GDI+的Image类封装了对BMP.GIF.JPEG.PNG.TIFF.WMF(Windows元文件)和EMF(增强WMF)图像文件的调入.格式转换以及简单处理的功能 ...

  3. robotframework笔记25

    library文档工具(Libdoc) Libdoc是机器人框架内置的工具生成的关键字的文档 测试库和资源文件的HTML和XML格式. 前 格式适用于人类,后者 骑 和其他 工具. Libdoc显示库 ...

  4. 笔记6:winfrom连接sql server 进行数据交换

    今天的作业是用winfrom窗体做一个留言板,如图: 要求和数据库有查询和添加功能.下拉框里的值是直接获取数据库中的值 一.连接数据库,获取表中数据 //创建一个存数据的表 DataTable tab ...

  5. CF---(452)A. Eevee

    A. Eevee time limit per test 1 second memory limit per test 256 megabytes input standard input outpu ...

  6. 用Visual C#向access添加数据

    (1)创建并打开一个OleDbConnection对象. (2)创建一个插入一条记录的SQL语句. (3)创建一个OleDbCommand对象. (4)通过此OleDbCommand对象完成对插入一条 ...

  7. Sum Root to Leaf Numbers [LeetCode]

    Problem description: http://oj.leetcode.com/problems/sum-root-to-leaf-numbers/ Basic idea: To store ...

  8. sql 语句随机时间存储过程

    CREATE PROC [dbo].[Proc_GetRandomTime](@startTime datetime,@endTime datetime,@date datetime output ) ...

  9. [译]Quartz 框架 教程(中文版)2.2.x 之第一课 开始使用Quartz框架

    第一课:开始使用Quartz框架 在你使用调度器之前,需要借助一些具体的例子去理解(谁愿意只是猜啊?).你可以使用SchedulerFactory类来达到程序调度的目的.有一些Quartz框架的用户可 ...

  10. 在vim中执行外部命令

    11.7.5  在Vim编辑器中执行Shell命令 有时需要在Vim编辑器中执行Shell命令,例如需要验证一个Shell命令是否正确,以便写入脚本中:需要在文件中引用某个Shell命令的输入等.本小 ...