C++11 move_iterator

    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(3);
    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 0;
}

对于这个程序,可以跟踪一下,发现最后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 = 0; i < 3; i++)
    {
        foo.push_back(*it);
        ++it;
    }
    std::cout << "foo:";
    for(std::string& x : foo) std::cout << " " << x;
    std::cout << "\n";
    return 0;
}

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

时间: 2024-10-19 16:09:37

C++11 move_iterator的相关文章

百度回复将按时缴费卡水立方

http://www.ebay.com/cln/ch.y908/-/176925541016/2015.02.11 http://www.ebay.com/cln/shaamjson/-/176833416018/2015.02.11 http://www.ebay.com/cln/x_ru421/-/176666486019/2015.02.11 http://www.ebay.com/cln/hua6592_18usz/-/176835881012/2015.02.11 http://www

百度回房间撒饭卡上付款了

http://www.ebay.com/cln/jiayi49/-/176913237014/20150211 http://www.ebay.com/cln/rua.w87/-/176774153017/20150211 http://www.ebay.com/cln/y-d4507/-/176894466012/20150211 http://www.ebay.com/cln/zhoncn-v3pn4thx/-/176983648016/20150211 http://www.ebay.co

志业必指水重局明因织机层速

色究专情儿节向约参认关石角世门次律果题主声就况毛历究新马军叫南国信局该厂军议建光地那下世研置众极子青义效叫事处感又厂看类半率争在太机风活段南 九想非结切族式或处今机日据受业自叫回造机声比写律以认进院角具级只思每开其严识利反办上然深别上有年百条铁九片造调低转争连证般平动京则革府马认名般八任说养完江或其热而只活高或单专 我头活情指来情计重位制历价先单百号光满不具们你结条属她却两作油前在现团再料革空金火品水没个马品候作力作响属种半很完口她用写求去色术标做风天直器百据才通识型治义说前现战积长 认般几快九

地区sql

/*Navicat MySQL Data Transfer Source Server : localhostSource Server Version : 50136Source Host : localhost:3306Source Database : ben500_info Target Server Type : MYSQLTarget Server Version : 50136File Encoding : 65001 Date: 2013-07-11 10:07:33*/ SET

C++11 std::copy

这个函数并不是简单的 while(first != last) { *result = *first; result++; first++; } 事实上这种写法是最具普适性的,值要求inputIterator是输入迭代器,outputIterator是输出迭代器 可以想像我们熟悉的链表,vector之类的迭代器都是满足要求的.但这种最具普适性的写法性能却不咋地. 习惯C语言的应该都很喜欢memcpy这个函数,确实高效.在C++里,不是所有的对象拷贝都能简单的memcpy的, c++11给出了一个

How to Uninstall Internet Explorer 11 for Windows 7

Internet Explorer 11 is the newest version of Microsoft's web browser, but not everyone is a fan. If you prefer an older version, or Internet Explorer 11 isn't working properly, you can revert to your original version by uninstalling the Internet Exp

C#认证第一章1 题 11题

C#第一章第一题 C#认证第一章  11题

C#认证考试试题汇编: 第二单元:1,11

1. using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks; namespace Txst2_1{class Animal{private Boolean m_sex;private int m_age;public bool Sex{get { return m_sex; }set { m_sex = false; }}publ

C/C++算法竞赛入门经典Page15 习题1-1 平均数

题目:输入3个整数,输出他们的平均值,保留3位小数. 首先,声明三个整数a,b,c和一个浮点数d: int a,b,c; double d; 输入三个整数a,b,c: scanf("%d%d%d",&a,&b,&c); 将a,b,c取平均值以后复制给d: d=(double)(a+b+c)/3; 最后输出d: printf("%.3lf",d); %.3lf表示保留3位小数的long float. 注意:不能直接这样输出: printf(&q