Effective STL 中文版记录(五)

Effective STL 章节(五)

——50条有效使用STL的经验(29/50)
迭代器专项



第二十六条、iterator优于const_iterator、reverse_iterator及const_reverse_iterator

C++ 迭代器(Iterator)是一种抽象的工具,用来遍历容器(如数组、链表、集合等)中的元素,而无需关心容器的底层实现。
迭代器类似于指针,但比指针更强大和灵活。C++ 标准库中的大多数容器(如 vector、list、set 等)都支持迭代器操作。

通常情况下,迭代器支持以下操作:
解引用(Dereference):获取迭代器当前指向的元素。通过 *it 或 it-> 来访问元素。
前进(Increment):将迭代器移动到容器中的下一个元素。使用 ++it(前置)或 it++(后置)来前进。
后退(Decrement):将迭代器移动到容器中的上一个元素。使用 --it(前置)或 it–(后置)来后退。
比较(Comparison):可以比较两个迭代器是否相等(==)或不等(!=)。通常用于判断迭代器是否已到达容器的末尾。

那么本条提到的四个迭代器意味着什么?

考虑指针,一般包含:T*, const T*
那么iterator对应T*,const_iterator对应const T*
通样的,reverse_interator 和 const_reverse_iterator分别对应T* 和 const T*,区别在于作递增操作时,迭代器是反向遍历的

这一条的本意是说,尽量使用iterator,因为很多函数只能以iterator为参数,后面三个是不能输入的

第二十七条、使用distance和advance将容器的const_iterator转换成iterator

如果说有const型的迭代器,而必须要转换成非const型,怎么办

遵守第二十六条的情况下,一般就不会出现这种问题,所以这一条的目的还是为了强化第二十六条

但是没办法,总会出现这种问题,所以解决方案也得有,也就是使用distance和advance来转换

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    // 定义一个 const_iterator
    std::vector<int>::const_iterator const_it = vec.cbegin() + 2; // 指向值为3的位置
    auto distance = std::distance(vec.cbegin(), const_it); // 计算 const_iterator 到 vec.begin() 的距离
    std::vector<int>::iterator it = vec.begin(); // 定义一个 iterator,指向 vec.begin()
    std::advance(it, distance); // 将 iterator 推进到 const_iterator 所指向的位置
}

也就是重新创建一个非const的迭代器,移动到const迭代器所指的位置,而不是强制转换

第二十八条、正确理解由reverse_iterator的base()成员函数所产生的iterator的用法

调用reverse_iterator的base()函数能够获得对应的iterator,但是真的是我们理解的iterator吗

举例,以下代码能够创建一个iterator,来自一个reverse_iterator

vector<int> v;
v.reverse(5);

for (int i= 0; i< 5; ++i)
    v.push_back(i);
vector<int>::reverse_iterator ri = find(v.rbegin(), v.rend(), 3);  // 定义reverse_iterator
vector<int>::iterator i = ri.base();  // 取得"对应的"iterator

实际上在内存里是这样的:
在这里插入图片描述
这样设置的结果是,当对i或者ri插入元素时,元素的位置都是在3,4之间,也就是v[3]的位置

所以实际上在插入时,i和ri没区别,都是一样的

但是当删除时,则不一样了,因为ri指向3,删除后是1 2 4 5,而如果删除i指向的地方,则变成了1 2 3 5

这明显不是我们希望看到的,所以需要进行--i再删除

注意,必须是--i,而不能用--ri.base(),因为返回值是指针的函数有可能在这行无法通过编译,先用i接住,再修改

第二十九条、对于逐个字符的输入请考虑使用istreambuf_iterator

这点是为了效率考虑,通常是使用istream_iterator,但是它会跳过空白字符

使用istreambuf_iterator一方面能够保留这些空白,另一方面由于它是直接从缓冲区读,而不是从输入流读取,所以会更快

(输入流是通过输入缓冲区生成的,所以省了一些工作)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值