C++11之基于范围的for循环
上述的几种遍历方式的共同点就是都需要写明循环的一个范围。对于我们需要完整的遍历一个有范围的集合/数组时,完全可以让编译器自动计算出范围。在使用范围遍历的方式遍历stl的容器时,如果你使用auto声明迭代器的变量,那么推导出来的类型是迭代器解引用后的对象。但范围遍历不能适用于所有情况,范围遍历的条件就是循环迭代的范围必须是可确定的。在C++98标准中,当我们遍历数组时,一般方法就是下标遍历和指针遍历
系列文章
C++11之正则表达式(regex_match、regex_search、regex_replace)
C++11之线程库(Thread、Mutex、atomic、lock_guard、同步)
C++11之智能指针(unique_ptr、shared_ptr、weak_ptr、auto_ptr)浅谈内存管理
C++11之强制类型转换(static_cast,const_cast,dynamic_cast,reinterpret_cast)
C++11之右值引用:移动语义和完美转发(带你了解移动构造函数、纯右值、将亡值、右值引用、std::move、forward等新概念)
C++11之内联名字空间(inline namespace)和ADL特性(Argument-Dependent name Lookup)
C++11之decltype类型推导(使用场景、推导四规则、cv限定符)
基于范围的for循环
C++98遍历方式
在C++98标准中,当我们遍历数组时,一般方法就是下标遍历和指针遍历。
int arr[] = { 1,2,3,5,6 };
// 下标遍历
for(size_t i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i)
{
std::cout << arr[i] << " ";
}
std::cout << std::endl;
// 指针遍历
int* p = arr;
for(p = arr; p < arr + sizeof(arr) / sizeof(arr[0]); ++p)
{
std::cout << *p << " ";
}
std::cout << std::endl;
当然还有一种遍历方式,需要包含<algorithm>
头文件的for_each
遍历。参数依次是:起始地址、结束地址、回调函数。地址是左闭右开区间[begin,end)
。
#include <iostream>
#include <algorithm>
void print(const int& elem)
{
std::cout << elem << " ";
}
// for_each遍历
std::for_each(arr, arr + sizeof(arr) / sizeof(arr[0]), print);
std::cout << std::endl;
C++11 范围遍历
上述的几种遍历方式的共同点就是都需要写明循环的一个范围。对于我们需要完整的遍历一个有范围的集合/数组时,完全可以让编译器自动计算出范围。因此C++11引入了基于范围的for循环。
格式:for(迭代的变量:数组){}
现在我们使用范围遍历对数组进行遍历。
for(const int& e: arr)
{
std::cout << e << " ";
}
std::cout << std::endl;
然后我们可以在这里加入auto
自动类型(C++11),遍历将会更加简单。
for (const auto& elem : arr)
{
std::cout << elem << " ";
}
std::cout << std::endl;
但范围遍历不能适用于所有情况,范围遍历的条件就是循环迭代的范围必须是可确定的。例如string
、array
、vector
、list
、map
等都是可以正常使用的。而用户自定义写的类则需要自行提供自增运算符重载和赋值运算符重载。
int* ptr = arr;
for(auto elem : ptr)
{
std::cout << elem << " ";
}
std::cout << std::endl;
遍历没有明确范围的数组,是不能使用范围遍历方法的。
在使用范围遍历的方式遍历stl的容器时,如果你使用auto声明迭代器的变量,那么推导出来的类型是迭代器解引用后的对象。
std::vector<int> vec{ 1,5,6,9,4 };
for (const auto iter = vec.begin(); iter != vec.end(); ++iter)
{
std::cout << *iter << " ";
}
std::cout << std::endl;
for(const auto& elem : vec)
{
std::cout << elem << " ";
}
std::cout << std::endl;
这里就需要注意了前者iter
类型是迭代器对象,后者elem
是解引用后的对象。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)