【读书笔记】【深入应用C++11】1.4 基于范围的for循环

摘自:深入应用C++:代码优化与工程级应用

1.4.1 for循环的新用法

std::for_each()

使用std::for_each()做循环,不需要关心迭代器的概念,只需要关心容器的类型。如:

#include <algorithm>
void do_count(int n)
{
        cout<<n<<endl;
}
vector<int> vect={1,2,3,4,5,6,7,8,9,0};
std::for_each(vect.begin(),vect.end(),do_count);

第三个参数可以用函数指针,也可以用lambda表达式。

基于范围的for循环

在C++11中,提供了基于范围的for循环。如:

vector<int> vect={1,2,3,4,5,6,7,8,9,0};
for(auto num:vect)
{
        cout<<num<<endl;
}

对于冒号前面的局部变量声明,只要能够支持容器类型的隐式转换即可。如:

vector<long long int> vect={1,2,3,4,5,6,7,8,9,0};
for(int num:vect)
{
        cout<<num<<endl;
}

如果要修改容器中的值,需要使用引用。如:

vector<int> vect={1,2,3,4,5,6,7,8,9,0};
for(int &num:vect)
{
        num++;
        cout<<num<<endl;
}

1.4.2 基于范围的for循环的使用细节

  • 基于范围的for循环,与普通for循环一样,遵循容器本身的特性:

    • 对于map容器,var(元素)的类型是:std:pair,需要使用var.first和var.second来提取键值。
    • 对与map容器,var.first是只读的(const T&)。
    • 对于set容器,var(元素)是只读的。
    map<string,int> mm={{"Hello",1},{"World",2}};
    for(pair<string,int> var:mm)
    {
        cout<<var.first<<" "<<var.second<<endl;
    }
  • 基于范围的for循环,冒号后面的表达式只会被计算一次。
  • 基于范围的for循环,是普通for循环的语法糖。与普通for循环一样,迭代时修改容器可能会导致迭代器失效。
    for(auto var:array)
    {
        cout<<var<<endl;
    }

等价于:

    for(auto begin=array.begin(),end=array.end();begin!=end;begin++)
    {
        cout<<*begin<<endl;
    }

1.4.3 让基于范围的for循环支持自定义类型

为了使自定义的数据类型支持基于范围的for循环,需要定义begin和end迭代器。
编译器通过以下方式查找begin和end迭代器:

  • 普通数组,begin为数组的首地址,end为首地址加数组长度。
  • 类对象,查找内部的begin和end成员函数。
  • 否则,试图使用全局的begin和end函数。

基于范围for循环的自定义类型实现

待续

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章