当前位置:首页 > 芯闻号 > 充电吧
[导读]C++11系列-区间迭代在我前面介绍C++11的文章中,我提到C++11将会带来一些实用的改进。我的意思是它将移除一些不必要的打字和其它影响快速编码的壁垒。我前面讲过的auto关键字就是一个例子;现在

C++11系列-区间迭代

在我前面介绍C++11的文章中,我提到C++11将会带来一些实用的改进。我的意思是它将移除一些不必要的打字和其它影响快速编码的壁垒。我前面讲过的auto关键字就是一个例子;现在我想讲一下区间迭代(range-based for loop)。

区间迭代的基本语法

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

vectorvec;
vec.push_back( 10 );
vec.push_back( 20 );

for (int i : vec )
{
    cout << i;
}

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

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

修改vector的值

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

vectorvec;
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的类迭代。

#includeusing 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中的元素。这是为了不使代码变长而影响代码的主要结构,所以并没添加返回引用类型的函数。

区间迭代提升性能?

在我使用GCC4.6的有限的测试中,我并没看到区间迭代相对于标准STL迭代的性能提升,但好像可以和STL中的for_each拥有同样的性能。

编译器支持

不幸的是,区间迭代的编译器支持的不好。MSVC11以后开始支持,GCC是4.6以后支持。


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

1月6日消息,市场调研机构最新数据显示2022年W52中国折叠屏手机市场,OPPO Find N2系列取得市场份额第一。

关键字: vivo 迭代 折叠屏手机

其实在 c++语言里面const修饰的才算是一个真正的常量,在 c 语言中 const 可以说是个“冒牌货”。为什么会这样?其实是 c++ 编译器对 const 进行了加强,当 c++ 编译器遇到常量声明时,不会像 c...

关键字: c++ C语言 const

返回函数的引用去初始化一个新的引用这个和前面一样,都是不会产生副本,但是现在是用返回值去初始化一个引用声明c,也就是说这时候变成了变量temp的别名,在c的生命周期内temp是一直有效的,这样做完全可以。

关键字: c++ 返回值 引用声明

摘要:首先介绍了牛顿-拉夫逊算法和P-Q分解法的基本概念以及paladinDesignBase软件的基本功能,然后介绍了某2机5节点电力系统案例,接下来构建该系统的单线图,输入已知参数,设置潮流计算条件,得出在不同精度下...

关键字: 电力系统 P-Q分解法 迭代

C++是一种面向对象的高级程序设计语言,是C语言的超集。

关键字: c++ C语言

7月30日消息,阿里巴巴客户体验事业部(简称:阿里CCO)资深专家董锐应邀出席某论坛时透露,8月天猫官方服务将迎来新一轮升级,预计有50余家天猫旗舰店率先完成数字服务系统迭代。 董锐直言,2020上半

关键字: 天猫 旗舰店 迭代 数字服务系统

如果说,特斯拉的国产化,为中国新能源汽车市场又打了一剂强心针,那么续航短、掉电快、换电池贵、贬值快……这些初代新能源汽车的尴尬,能逐渐随着技术迭代而化解吗?1月12日,10位车主拿到了中国制造的特斯拉Model 3,而...

关键字: 国产 特斯拉 迭代

分析:这是Adobe 公司2007 年校园招聘的最新笔试题。这道题除了考察应聘者的C++ 基本功底外,还能考察反应能力,是一道很好的题目。 在Java 中定义了关键字final ,被final 修饰的

关键字: c++ class

泛型算法中的定制操作很多算法都会比较输入序列中的元素,通过定制比较动作,可以控制算法按照编程者的意图工作。本文以string排序为例进行说明,首先是缺省的排序动作: vector v{"This","

关键字: c++

为什么是lambda?讲了这么多天的lambda表达式,有一个很基本的问题没有回答:为什么叫lambda表达式呢?首先这个lambda就是罗马字母λ,lambda表达式即λ表达式。数学上有一个概念叫λ

关键字: c++
关闭
关闭