STL中list如何实现普通迭代器隐式类型转换成const迭代器

首先确保自己知道了list的大致实现原理。那么当我们自制一个iterator时如果不加以注意,可能会发生如下情况:

这时就会非常困惑,我们明明没有对权限进行放大,为什么编译器还会报错呢?

这是因为在泛型编程中,如果我们没有专门定义一个拷贝构造函数,那么默认的会以自己的类型为基准去考虑参数类型。

所以这里原因很清楚了,当我们定义一个const_iterator时,其默认拷贝构造的参数也是const_iterator。

因此,编译器才会报错说iterator<int, int&, int*>无法转化为iterator<int, const int&, const int*> 

不要用int可以隐式转化成const int的思维去考虑类模板。虽然iterator和const_iterator在底层调用的都是同一个类模板,但是在实例化的时候,编译器会认为这是两个不同的类型!

就好比说当 template<class T> 实例化出int和char两种类型时,总不能说int和char是同一种类型吧。

list所使用的是template泛型编程,当我们定义一种泛型时,更加需要确保其与模板匹配。要不然会更加乱套了。

可以试想一下,template<class T> == template<class const T>这很奇怪吧,因此编译器在编译时会把它们区分成两种不同的类型。

那么回到问题,解决方式也很简单,我们只需要在iterator类中定义一个构造函数即可

因为权限只能缩小,那我们就假设所有传进来的参数都是非const类型即可,即iterator。那么即便我自己是const_iterator,也可以使用这个函数获取节点node

对此,我们可以看看SGI版的list源代码加以证明:

我们发现,当使用iterator作为参数,如果实例化对象是iterator或const_iterator时,就会自动调用这个拷贝构造

而如果参数是const_iterator时,便会调默认拷贝构造。因为我们定义的拷贝构造参数为iterator与之不匹配。当然前提对象也是const_iterator,否则就是权限放大(编译器会报错类型不匹配)。

对于反向迭代器而言道理相同,其拷贝构造本质上还是调用正向迭代器的相关拷贝构造。

对象是过程的抽象,线程是调度的抽象。---James O Coplien


如有错误,敬请斧正

  • 9
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

就要 宅在家

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

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

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

打赏作者

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

抵扣说明:

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

余额充值