Effective Modern C++[实践]->优先使用 const_iterator 而非 iterator

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

  1. 只要有可能就应该使用const
  2. 优先使用 const_iterator 而不是 iterator。任何时候只要你需要一个迭代器而其指涉内容没有修改必要时,你就应该使用const_iterator
  3. 在最大泛型代码中, 相对于它们的成员函数部分, 优先使用 begin endrbegin 等的非成员函数版本。因其更通用。

迭代器

何谓c++迭代器

迭代器是c++标准模板库(STL)的6大组成(容器、算法、迭代器、函数对象、适配器、内存分配器)之一。迭代器用于指向STL容器类的内存地址。为了更好地理解,在某种程度上,可以将它们与指针联系起来。

迭代器充当了将算法连接到STL容器的桥梁,并允许修改容器内的数据。它们允许您遍历容器、访问和赋值,并在它们上运行不同的操作符,以获得所需的结果。

根据迭代器的功能,它们可以分为五个主要类别:

  1. 输入迭代器(Input Iterators): 它们是所有迭代器中最弱的,而且功能非常有限。它们只能用在单遍算法中,即那些顺序处理容器的算法,这样就不会有任何元素被访问超过一次。
  2. 输出迭代器(Output Iterators):就像输入迭代器一样,它们的功能也非常有限,只能在单遍算法中使用,但不是用于访问元素,而是用于分配元素。
  3. 前向迭代器(Forward Iterator): 它们比输入和输出迭代器的层次更高,包含这两个迭代器中的所有特性。但是,正如它的名字所暗示的那样,它们也只能向前移动,而且也是一次一步。
  4. 双向迭代器(Bidirectional Iterators): 它们拥有前向迭代器的所有特性,同时克服了前向迭代器的缺点,因为它们可以向两个方向移动,这就是为什么它们被称为双向的原因。
  5. 随机访问迭代器(Random-Access Iterators): 随机访问迭代器实现了双向迭代器的所有功能,并且还具有非顺序访问范围的能力: 通过向迭代器应用偏移量值,可以直接访问远处的元素,而无需遍历中间的所有元素。这些迭代器具有与标准指针类似的功能(指针是此类别的迭代器)。
类别 特性 有效表达
所有类别 复制构造 复制赋值运算符 析构 X b(a);
b = a;
可以递增 ++a
a++
随机访问 双向 向前 输入 支持平等/不平等比较 a == b
a != b
可以作为 右值 *a
a->m
输出 可以作为 左值
(仅适用于 可变迭代器类型
*a = t
*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 +=n
a -=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 容器元素并对它们执行某些操作。
  • 容器的内部结构无关紧要,因为迭
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-西门吹雪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值