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进行包装

最新文章

  1. MySQL 忘记root密码解决办法
  2. Root--超级用户
  3. windows服务器的DDOS防御,
  4. 在虚机中安装CentOS
  5. css之overflow:细探之下有意想不到的结果
  6. 【BZOJ-2809】dispatching派遣 Splay + 启发式合并
  7. C#中IDisposable学习
  8. jQuery 参考手册 - 效果
  9. hdoj 4324 Triangle LOVE【拓扑排序判断是否存在环】
  10. STM8S学习笔记-时钟控制2
  11. Windows10笔记本双显卡导致的启动黑屏解决办法之一
  12. office2013破解工具
  13. html页面高度自适应
  14. Git----GitHub Desktop的入门及使用
  15. 我发起了一个 用 C# 写 的 浏览器 开源项目 HtmlCore
  16. 微服务架构中APIGateway原理
  17. 基于Centos搭建 Discuz 论坛
  18. 160CrackMe练手 002
  19. 100度享乐电商网 CSS
  20. Spring 注解@Component,@Service,@Controller,@Repository

热门文章

  1. CentOS报错:Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7&amp;arch=x86_64&amp;repo=os&amp;infra=stock32 error was 14: curl#6 - &quot;Could not resolve host: mirrorlist.centos.org; Unknown error&quot;
  2. Linux编程
  3. Servlet后续的尾(yi)巴--------Filter过滤器
  4. 错误:Error:未定义标识符&quot;_TCHAR&quot;
  5. 如何查看,关闭和开启selinux
  6. Problem 2020 组合(FOJ)
  7. js ——算法
  8. JS访问剪切板中的图片
  9. ASP.NET MVC学习之控制器篇(二)
  10. java枚举类