建湖做网站的公司网站建设分期收费
在C++03/98中,不同的容器和数组,遍历的方法不尽相同,写法不统一,也不够简洁,而C++11基于范围的for循环以统一,简洁的方式来遍历容器和数组,用起来更方便了。
for循环的新用法
#include <iostream>
 #include <vector>
 using namespace std;
int main()
 {
     vector<int> arr = {1, 2, 3, 4, 5};
    for(auto it = arr.begin(); it != arr.end(); it++)
     {
         cout << *it << endl;
     }
    return 0;
 }
上面借助auto关键字,省略了迭代器的声明。
现在,在C++11中终于有了基于范围的for循环。
#include <iostream>
 #include <vector>
 using namespace std;
int main()
 {
     vector<int> arr = {1, 2, 3, 4, 5};
    for(auto n : arr)
     {
         cout << n << endl;
     }
    return 0;
 }
在上面的基于范围的for循环中,n表示arr中的一个元素,auto则是让编译器自动推导出n的类型。在这里,n的类型将被自动推导为vector中的元素类型int。
在n的定义之后,紧跟一个冒号(:),之后直接写上需要遍历的表达式,for循环将自动以表达式返回的容器为范围进行迭代。
对map的遍历方法
#include <iostream>
 #include <vector>
 #include <map>
 #include <string>
 using namespace std;
int main()
 {
     map<string, int> mymap = {{"1", 1}, {"2", 2}, {"3", 3}, {"4", 4}};
    for(auto& it :mymap)
     {
         cout << it.first << "\t" << it.second << endl;
     }
    return 0;
 }
这里需要注意两点:
1、for循环中it的类型是std::pair。因此,对于map这种关联性容器而言,需要使用it.first或者it.second来提取键值。
2、aut自动推导出的类型是容器中的value_type,而不是迭代器。
使用细节
#include <iostream>
 #include <vector>
 #include <map>
 #include <string>
 #include <set>
 using namespace std;
int main()
 {
     set<int> myset = {1, 2, 3, 4, 5};
    for(auto& it : myset)
     {
         cout << it++ << endl;
         ///arr.cpp:26:13: error: increment of read-only reference ‘it’
     }
    return 0;
 }
在该例子中使用了auto &定义了set<int>中元素的引用,希望能够在循环中对set的值进行修改,但是set的内部元素是只读的,因此,for循环中的auto &会被推导为const int &。
同样的细节也会出现在map的遍历中。基于范围的for循环中的std::pair引用,是不能够修改first的。
#include <iostream>
 #include <vector>
 #include <map>
 #include <string>
 #include <set>
 using namespace std;
vector<int> myarr = {1, 2, 4, 5};
vector<int>& get_vecotr()
 {
     printf("get vector....\n");
     return myarr;
 }
 int main()
 {
     for(auto it : get_vecotr())
     {
         cout << it << endl;
     }
    return 0;
 }
输出结果:

从上面的结果中可以看到,不论基于范围的for循环迭代了多少次,get_vector()只在第一次迭代之前被调用。
因此,对于基于范围的for循环而言,冒号后面的表达式只会被执行一次。
