1.1 for循环的新用法
一般情况下在C++下遍历一个容器的方法是这样的
现在,C++11中有了基于范围的for循环,那么之前我们写的遍历容器的方法就可以写成这样
在上面的代码中可以指定item的类型,如下的代码也是能够通过编译的
上面的代码都是对容器进行只读式访问,在for循环中也可以对容器中的值进行修改操作:
std::vector<int> array = {1, 2, 3, 4, 5};
for(auto it=array.begin(), it !=array.end(); ++it)
{
std::cout << *it << "\t";
}
对于刷洗STL的用户的话知道在<algorithm>中有一个函数叫for_each算法来完成上诉的功能。
void do_cout(int n)
{
std::cout << n << "\t";
}
std::for_each(array.begin(), array.end(), do_cout);
for_each()对比for循环,最大的好处是不再需要关注迭代器的概念,只需要关心容器中的元素类型即可。现在,C++11中有了基于范围的for循环,那么之前我们写的遍历容器的方法就可以写成这样
for(auto item : array)
{
cout << item << "\t";
}
代码解释:在上面的for循环中,item是array中的一个元素,auto则是让编译器自动推导出item的类型(在上面的使用情况中item被自动推导为int)。在item的定义之后,紧跟着一个冒号“:”,之后直接写上需要遍历的表达式,for循环将自动以表达式返回的容器为范围进行迭代。在上面的代码中可以指定item的类型,如下的代码也是能够通过编译的
for(char item : array)
{
cout << item << "\t";
}
但是在实际运行过程中过产生数据溢出错误,但是这个错误编译器不能检查出来上面的代码都是对容器进行只读式访问,在for循环中也可以对容器中的值进行修改操作:
for(auto& item : array)
{
cout << item++ << "\t";
}
这样在上面的代码中就对容器中的元素进行加1操作。
1.2 基于范围的for循环的使用细节
(1)auto自动推导出的类型是容器中的value_type,而不是迭代器
(2)在使用for循环的时候,要注意容器自身的属性
(3)对于基于范围的for循环而言,冒号后面的表达式只会被执行一次
(4)若是在基于范围的for循环中对容器进行了增加和删除操作,将会使得迭代失效,导致意外的结果产生。
std::map<std::string, int> array = {{"a", 1}, {"b", 2}, {"c", 3}};
for(auto& item : array)
{
std::cout << item.first << "->" << item.sencond << std::endl;
}
注意:上面for循环的推导变量item取first和second元素的时候使用的是“.”操作符,而不是“->”操作符,是因为item不是迭代器类型的(2)在使用for循环的时候,要注意容器自身的属性
std::set<int> array = {1, 2, 3};
for(auto& item : array)
{
std::cout << item++ << std::endl;
}
注意:上面的代码是错误的,因为set中的元素是只读的,这是由set的属性决定的(3)对于基于范围的for循环而言,冒号后面的表达式只会被执行一次
(4)若是在基于范围的for循环中对容器进行了增加和删除操作,将会使得迭代失效,导致意外的结果产生。