优先使用const_iterator而非iterator
- 只要有可能就应该使用
const- 优先使用
const_iterator而不是iterator。任何时候只要你需要一个迭代器而其指涉内容没有修改必要时,你就应该使用const_iterator- 在最大泛型代码中, 相对于它们的成员函数部分, 优先使用
begin、end、rbegin等的非成员函数版本。因其更通用。
迭代器
何谓c++迭代器
迭代器是
c++标准模板库(STL)的6大组成(容器、算法、迭代器、函数对象、适配器、内存分配器)之一。迭代器用于指向STL容器类的内存地址。为了更好地理解,在某种程度上,可以将它们与指针联系起来。
迭代器充当了将算法连接到STL容器的桥梁,并允许修改容器内的数据。它们允许您遍历容器、访问和赋值,并在它们上运行不同的操作符,以获得所需的结果。
根据迭代器的功能,它们可以分为五个主要类别:
- 输入迭代器(
Input Iterators): 它们是所有迭代器中最弱的,而且功能非常有限。它们只能用在单遍算法中,即那些顺序处理容器的算法,这样就不会有任何元素被访问超过一次。 - 输出迭代器(
Output Iterators):就像输入迭代器一样,它们的功能也非常有限,只能在单遍算法中使用,但不是用于访问元素,而是用于分配元素。 - 前向迭代器(
Forward Iterator): 它们比输入和输出迭代器的层次更高,包含这两个迭代器中的所有特性。但是,正如它的名字所暗示的那样,它们也只能向前移动,而且也是一次一步。 - 双向迭代器(
Bidirectional Iterators): 它们拥有前向迭代器的所有特性,同时克服了前向迭代器的缺点,因为它们可以向两个方向移动,这就是为什么它们被称为双向的原因。 - 随机访问迭代器(
Random-Access Iterators): 随机访问迭代器实现了双向迭代器的所有功能,并且还具有非顺序访问范围的能力: 通过向迭代器应用偏移量值,可以直接访问远处的元素,而无需遍历中间的所有元素。这些迭代器具有与标准指针类似的功能(指针是此类别的迭代器)。
| 类别 | 特性 | 有效表达 | |||
|---|---|---|---|---|---|
| 所有类别 | 复制构造 、 复制赋值运算符 和 析构 | X b(a); |
|||
| 可以递增 | ++a |
||||
| 随机访问 | 双向 | 向前 | 输入 | 支持平等/不平等比较 | a == b |
| 可以作为 右值 | *a |
||||
| 输出 | 可以作为 左值 (仅适用于 可变迭代器类型 ) |
*a = t |
|||
| 默认可构建 | X a;X(); |
||||
| 多遍:解引用和递增都不会影响可解引用性 | { b=a; *a++; *b; } |
||||
| 可以递减 | --a;a--;*a--; |
||||
| 支持算术运算符 + 和 - | a + n;n + a;a - n;a - b; |
||||
| 不等式比较( < 、 > 、 <= 和 >= 迭代器之间 | a<b a>b a<=b a>=b |
||||
| 支持复合赋值操作 += 和 -= | a +=na -=n |
||||
| 支持偏移解引用运算符 ( [] ) | a[n] |
||||
示例:
#include <algorithm>
#include <iostream>
#include <map>
#include <set>
#include <string>
using namespace std;
void print_map(std::string_view comment, const std::map<string, int> &m,int type) {
std::cout << comment ;
switch (type) {
case 98: {
for (std::map<std::string, int>::const_iterator it = m.begin();
it != m.end(); it++) {
std::cout << it->first << " = " << it->second << "; ";
}
} break;
case 11: {
for (const auto &n : m) {
std::cout << n.first << " = " << n.second << "; ";
}
} break;
case 17: {
for (const auto &[key, value] : m) {
std::cout << '[' << key << "] = " << value << "; ";
}
} break;
}
cout<<endl;
}
int main() {
set<map<string, int> > set1;
set <map <string, int >> :: iterator ps;
set1.insert({
{
"1", 1}});
set1.insert({
{
"2", 2}});
set1.insert({
{
"3", 3}});
set1.insert({
{
"4", 4}});
std::cout << "c++98 迭代" <<endl;
for (ps = set1.begin(); ps != set1.end(); ps++) {
print_map(" ", *ps,98);
}
cout<<endl;
std::cout << "c++11 迭代" <<endl;
for (ps = set1.begin(); ps != set1.end(); ps++) {
print_map(" ", *ps,11);
}
cout<<endl;
std::cout << "c++17 迭代" <<endl;
for (ps = set1.begin(); ps != set1.end(); ps++) {
print_map(" ", *ps,98);
}
}
打印输出:
c++98 迭代
1 = 1;
2 = 2;
3 = 3;
4 = 4;
c++11 迭代
1 = 1;
2 = 2;
3 = 3;
4 = 4;
c++17 迭代
1 = 1;
2 = 2;
3 = 3;
4 = 4;
迭代器的主要用途
- 迭代器的主要目标是访问 STL 容器元素并对它们执行某些操作。
- 容器的内部结构无关紧要,因为迭

本文主要介绍了C++迭代器,它是标准模板库的重要组成部分,用于指向容器内存地址,可分为五类。阐述了迭代器的用途、语法、与指针的区别及基本操作,还说明了其好处。同时指出C++98中迭代器使用不便,而C++11后获取和使用更简单,最后给出通用代码示例。
最低0.47元/天 解锁文章
741

被折叠的 条评论
为什么被折叠?



