tags:
- Cpp
STL Iterator - Range Access (Part II)
我们在第一部分提到,STL 迭代器相当于泛化的指针,它的作用就是为不同数据结构提供统一的遍历和访问接口。Range access 就是一组统一操作容器的标准库函数。这些函数可以提供对数据范围的起始位置、结束位置、大小和判断空信息的访问。其中很多函数我们已经见过很多遍了。
begin()
/ end()
这两个函数用于返回容器的起始和结束迭代器(或者指针)。
#include <vector>
int main(){
int custom_arr[] = {1, 2, 3};
std::vector<int> vec = {4, 5, 6};
auto arr_begin = std::begin(custom_arr); // return int*
// auto arr_begin = custom_arr.begin(); // illegal
*arr_begin = 10;
auto vec_begin = std::begin(vec); // return vector<int>::iterator
auto vec_begin1 = vec.begin(); // okay for STL containers
*vec_begin = 10;
return 0;
}
如果对象是标准库容器,你就可以写成下面那种形式。
cbegin()
/ cend()
这两个函数用于返回容器的常量迭代器(或指针)。也就是说,所返回的迭代器只能读,不能写。
#include <vector>
int main(){
int custom_arr[] = {1, 2, 3};
std::vector<int> vec = {4, 5, 6};
auto arr_begin = std::cbegin(custom_arr);
// *arr_begin = 10; // illegal
auto vec_begin = std::cbegin(vec);
// *vec_begin = 10; // illegal
return 0;
}
rbegin()
/ rend()
这两个 range access 函数很有意思,它返回的是反向的迭代器,用途是逆序遍历。它的作用如下图所示:
rbegin()
和 end()
并不相同,它们并不能比较,一个是正向迭代器,一个是反向迭代器。你可以用 base()
方法 (如 rbegin().base()
) 将反向迭代器转换成正向迭代器。
#include <vector>
#include <iostream>
int main(){
std::vector<int> vec = {4, 5, 6};
auto vec_rbegin = std::rbegin(vec);
for(; vec_rbegin != vec.rend(); ++vec_rbegin){
std::cout << *vec_rbegin << " ";
}
//auto vec_end = std::end(vec);
//if(vec_rbegin == vec_end){
// std::cout << "They are the same..." << std::endl;
//}
return 0;
}
// Prints 6 5 4
crbegin()
/ crend()
size()
返回容器或数组的元素个数。
empty()
检查容器是否为空。即元素个数是否为 0 。
data()
返回指向容器或数组底层数据存储的指针。常常用于与 C 接口交互。