zoukankan      html  css  js  c++  java
  • 区间迭代

    区间迭代的基本语法

    近来,基本上所有现代编程语言都有一种对一个区间写for循环的便捷方式。最终,C++也有了相同的概念;你可以给循环提供一个容器,它帮你迭代。前面我们已经在什么是C++11中看到了一些简单的例子。让我们回忆一下区间迭代的样子:

    vector<int> vec;
    vec.push_back( 10 );
    vec.push_back( 20 );
    
    for (int i : vec )
    {
        cout << i;
    }  

    上面代码打印一个名叫vec的vector的内容,用i去捕获vector里面的值,直至vector的最后。你也可以用auto代替类型便利的迭代复杂的数据结构。例如,迭代一个map:

    map<string, string> address_book;
    for ( auto address_entry : address_book )
    {
                cout  << address_entry.first << " < " << address_entry.second << ">" << endl;
    }  

    修改vector的值

    假如你想修改你正在迭代的容器的值,或者你想避免拷贝大对象,你可以用引用的变量遍历。比如,下面的迭代对一个整形vector中每个元素的值加1。

    vector<int> vec;
    vec.push_back( 1 );
    vec.push_back( 2 );
    
    for (int& i : vec )
    {
        i++; // increments the value in the vector
    }
    for (int i : vec )
    {
        // show that the values are updated
        cout << i << endl;
    }  

    区间意味着什么?

    Strings,arrays,和所有的STL容器可以被新的区间迭代方式迭代。但是如果你想让你自己的数据结构使用这个新语法怎么办?

    为了使这个数据结构可迭代,它必须类似于STL迭代器。

    • 这个数据结构必须要有begin和end方法,成员方法和独立函数都行,这两个方法分别返回开始和结束的迭代器
    • 迭代器支持*操作符、!=操作符、++方法(前缀形式,成员函数和独立函数都行)

    就这些!实现这五个函数,你就可以有一个支持区间迭代的数据结构。因为begin、end可以是非成员函数,你甚至可以适配现有数据结构而不用实现STL风格的迭代器。所有你要做的是创建你自己的支持*、前缀++和!=的迭代器,并且定义好自己的begin、end。

    区间迭代如此NICE。所以我怀疑大部分还不支持STL迭代模型的容器都会想添加某种适配方式以支持区间迭代。这里有一个小程序演示创建一个支持区间迭代的迭代器。这个例子里,我创建了一个固定Size是100的IntVector,并且可以被一个叫做Iter的类迭代。

    #include <iostream>
    
    using namespace std;
    
    class IntVector;
    
    class Iter
    {
        public:
        Iter (const IntVector* p_vec, int pos)
            : _pos( pos )
            , _p_vec( p_vec )
        { }
    
        // 这三个方法组成支持区间迭代的迭代器的基础
        bool
        operator!= (const Iter& other) const
        {
            return _pos != other._pos;
        }
    
        int operator* () const;
    
        const Iter& operator++ ()
        {
            ++_pos;
            return *this;
        }
    
        private:
        int _pos;
        const IntVector *_p_vec;
    };
    
    class IntVector
    {
        public:
        IntVector ()
        {
        }
    
        int get (int col) const
        {
            return _data[ col ];
        }
        Iter begin () const
        {
            return Iter( this, 0 );
        }
    
        Iter end () const
        {
            return Iter( this, 100 );
        }
    
        void set (int index, int val)
        {
            _data[ index ] = val;
        }
    
        private:
       int _data[ 100 ];
    };
    
    int
    Iter::operator* () const
    {
         return _p_vec->get( _pos );
    }
    
    
    int main()
    {
        IntVector v;
        for ( int i = 0; i < 100; i++ )
        {
            v.set( i , i );
        }
        for ( int i : v ) { cout << i << endl; }
    }

    注意这段代码中区间迭代时,不允许以引用修改IntVector中的元素。这是为了不使代码变长而影响代码的主要结构,所以并没添加返回引用类型的函数。

    原文博客:http://towriting.com/blog/2013/08/20/ranged-for-loop/

  • 相关阅读:
    信息收集渠道:文本分享类网站Paste Site
    泛域名Wildcard Domain
    分享Kali Linux 2017年第12周镜像文件
    同源策略Same-origin policy
    Wireshark如何选择多行
    GPP加密破解工具gpp-decrypt
    HTTP基础认证Basic Authentication
    HAXM 6.0.5显示不兼容Windows
    分享Kali Linux 2017年第11周镜像文件
    bitShark对Android版本的支持
  • 原文地址:https://www.cnblogs.com/ThatsMyTiger/p/7089840.html
Copyright © 2011-2022 走看看