如何将const_iterator转换为iterator类型迭代器?
要知道,C++ STL标准库为了方便用户更轻松地操作容器,每个容器的模板类都提供有丰富且实用的方法。在这些方法中,有些是以 const_iterator 类型迭代器作为参数,也就意味着在使用此类方法时,需要为其传入一个 const_iterator 类型的迭代器。注意,上面提到的 iterator、const_iterator、reverse_iterator 和 const_reverse_iterator 是 C++ STL 标准库提供了 4 种基础迭代器,关于它们各自的特性和功能可以阅读 《C++ STL迭代器》一节,这里不再重复赘述。
例如,vector 容器模板类中提供有 insert() 方法,该方法的语法格式如下:
iterator insert (const_iterator position, const value_type& val);
可以看到,如果想调用此格式的 insert() 方法,就需要为其传入一个 const_iterator 类型的迭代器。例如:注意,此方法有多种语法格式,这里仅列举了其中的一种。有关该方法的具体用法,读者可阅读《C++ STL vector插入元素》一节,这里不再做详细赘述。
#include <iostream> #include <vector> using namespace std; int main() { vector<int>value{ 1,2,3,4,5 }; //定义一个 const_iterator 类型的迭代器 vector<int>::const_iterator citer = value.cbegin(); value.insert(citer, 10); for (auto iter = value.begin(); iter != value.end(); ++iter) { cout << *iter << " "; } return 0; }程序执行结果为:
10 1 2 3 4 5
显然通过调用 insert() 方法,并将指向 value 容器中元素 1 位置处的 const_iterator 类型迭代器作为该方法的实参,就成功将 10 插入到了 value 容器的指定位置。那么,是不是给 insert() 方法传递其它类型迭代器就不行呢?当然不是,对于给 const_iterator 类型的迭代器传值,还可以使用 iterator 类型迭代器,但不能使用 const_reverse_iterator 和 reverse_iterator 类型迭代器,这是为什么呢?
实际上,当我们将某一类型的迭代器传递给 insert() 方法中 const_iterator 类型的 position 形参时,即便类型不匹配,编译器也不会立即报错,而是先尝试将其类型转换成 const_iterator 类型,如果转换成功,则程序仍可以正常执行;反之如果转换失败,编译器才会报错。
对于 C++ STL 标准库中的这 4 种基础迭代器来说,C++ 编译器的隐式转换仅支持以下 2 种情况:C++ 中,通常将编译器自行尝试进行类型转换的整个过程称为隐式转换(或者自动类型转换)。
- 将 iterator 类型的迭代器隐式转换为 const_iterator 类型的迭代器;
- 将 reverse_iterator 类型的迭代器隐式转换为 const_reverse_iterator 类型的迭代器。
有些读者可能会好奇,既然隐式转换无法做到,还有其他方式可以实现从 const_iterator 到 iterator、从 const_reverse_iterator 到 reverse_iterator 的转换吗?注意,以上 2 种隐式转换是单向的,即编译器只支持从 iterator 转换为 const_iterator,从 reverse_iterator 转换为 const_reverse_iterator,但不支持逆向转换。
很多读者可能会想到使用强制类型转换(const_cast)的方式。但可以明确的是,强制类型转换并不适用于迭代器,因为 const_cast 的功能仅是去掉某个类型的 const 修饰符,但 const_iterator 和iterator 是完全不同的 2 个类,同样 const_reverse_iterator 和 reverse_iterator 也是完全不同的 2 个类,它们仅仅是类名有 const 的差别,但并不是 const T 和 T 的关系。
这里给读者推荐一种实现方式,就是使用 advance() 和 distance() 这 2 个函数,其语法格式如下:
//将 const_iterator 转换为 iterator
advance(iter, distance<cont<T>::const_iterator>(iter,citer));
//将 const_reverse_iterator 转换为 reverse_iterator
advance(iter, distance<cont<T>::const_reverse_iterator>(iter,citer));
该实现方式的本质是,先创建一个迭代器 citer,并将其初始化为指向容器中第一个元素的位置。在此基础上,通过计算和目标迭代器 iter 的距离(调用 distance()),将其移动至和 iter 同一个位置(调用 advance()),由此就可以间接得到一个指向同一位置的 iter 迭代器。注意,在使用 distance() 函数时,必须额外指明 2 个参数为 const 迭代器类型,否则会因为传入的 iter 和 citer 类型不一致导致 distance() 函数编译出错。
举个例子:
#include <iostream> #include <vector> using namespace std; int main() { vector<int>value{ 1,2,3,4,5 }; //定义一个 const_iterator 类型的迭代器,其指向最后一个元素 vector<int>::const_iterator citer = --value.cend(); //初始化一个非 const 迭代器,另其指向 vector<int>::iterator iter = value.begin(); //将 iter 变成和 citer 同样指向的迭代器 advance(iter, distance<vector<int>::const_iterator>(iter, citer)); cout <<"*citer = " << *citer << endl; cout << "*iter = " << *iter << endl; return 0; }程序执行结果为:
*citer = 5
*iter = 5
注意,此方法的实现效率仍取决于目标容器的迭代器类型,如果是随机访问迭代器,则该方法的执行效率为 O(1);反之,则执行效率为 O(n)。
所有教程
- C语言入门
- C语言编译器
- C语言项目案例
- 数据结构
- C++
- STL
- C++11
- socket
- GCC
- GDB
- Makefile
- OpenCV
- Qt教程
- Unity 3D
- UE4
- 游戏引擎
- Python
- Python并发编程
- TensorFlow
- Django
- NumPy
- Linux
- Shell
- Java教程
- 设计模式
- Java Swing
- Servlet
- JSP教程
- Struts2
- Maven
- Spring
- Spring MVC
- Spring Boot
- Spring Cloud
- Hibernate
- Mybatis
- MySQL教程
- MySQL函数
- NoSQL
- Redis
- MongoDB
- HBase
- Go语言
- C#
- MATLAB
- JavaScript
- Bootstrap
- HTML
- CSS教程
- PHP
- 汇编语言
- TCP/IP
- vi命令
- Android教程
- 区块链
- Docker
- 大数据
- 云计算