C++ 为什么Scott Meyers建议选择“迭代器”而不是“常量迭代器”`
在《有效STL》一书的第26项中,Scott Meyers建议首选C++ 为什么Scott Meyers建议选择“迭代器”而不是“常量迭代器”`,c++,stl,iterator,C++,Stl,Iterator,在《有效STL》一书的第26项中,Scott Meyers建议首选迭代器,而不是常量迭代器。据我所知,他主要通过解释const\u迭代器不能与insert或erase等特定函数一起工作来证明这一点 但是常量迭代器不允许修改容器,这不是它的全部要点吗?也许更重要的是,它允许您在代码中表达这一意图 他是否应该建议默认使用const\u迭代器,并且仅当您需要修改容器时,才使用iterator 他在书中说的原因是: •某些版本的insert和erase需要迭代器。如果你想 调用这些函数时,必须生成迭代器
迭代器
,而不是常量迭代器
。据我所知,他主要通过解释const\u迭代器
不能与insert
或erase
等特定函数一起工作来证明这一点
但是常量迭代器不允许修改容器,这不是它的全部要点吗?也许更重要的是,它允许您在代码中表达这一意图
他是否应该建议默认使用const\u迭代器
,并且仅当您需要修改容器时,才使用iterator
他在书中说的原因是:
•某些版本的insert和erase需要迭代器。如果你想
调用这些函数时,必须生成迭代器。
常量和反向迭代器不行
•不可能隐式地将常量迭代器转换为迭代器,
以及第27项中描述的用于生成迭代器的技术
从常量迭代器开始,既不是普遍适用的,也不是保证的
要有效率
但是,非常重要的是,他继续说:
不要误以为这意味着常量迭代器是无用的
一般来说他们不是。它们对算法非常有用,
因为算法通常不关心它们使用哪种迭代器
与……合作。只要它们属于适当的类别。常量迭代器
对于许多容器成员函数也是可以接受的。它是
只有某些形式的插入和擦除比较挑剔
> P.>通常情况下,它强烈地依赖于上下文和情况。 < P>简短的答案是,迈尔斯在考虑C++ 11标准中的改进时,使用STL的最新实现时,认为
在讨论他首先给出反const_iterator
建议的原因并解释发生了什么变化之前,我需要澄清一个误解。你写道:
这不是常量迭代器的全部要点吗,它不允许修改容器
这是一个合理的假设,但实际上这并不是常量迭代器的目的。正如迈尔斯在第三版的有效C++中所解释的(写的,特别是C++ 11之前):
声明一个迭代器
常量
就像声明一个指针常量
(即,声明一个T*const
指针):不允许迭代器
指向不同的对象,但它指向的对象可以修改。如果您想要一个指向无法修改的内容的迭代器(即const t*
指针的STL类似物),那么您需要一个const\u迭代器
简而言之,const_迭代器
不能防止修改容器,它可以防止修改包含的值。这就是Meyers希望insert
与const\u迭代器
兼容的原因:它不会修改容器中已经存在的任何元素
erase
有点奇怪,因为它会导致包含的元素被销毁,这是一个非const
操作。但是请注意,元素的析构函数不是通过迭代器本身调用的;迭代器只是API提供的用于指定要擦除的项的方法。从语义上讲,常量迭代器
应该与迭代器
一样能够达到这一目的
现在,关于有效STL的建议及其后续的缩进,我将在这个问题上解释和引用一些有效的现代C++。在第13项中,“宁愿使用const_迭代器
s而不是iterator
s”,Meyers写道:
…在C++98中,常量迭代器
只有半心半意的支持。创建它们并不是那么容易,一旦你有了一个,你可以使用它的方式是有限的
…从非常量
容器中获取常量迭代器
没有简单的方法
一旦有了常量迭代器
s…插入(和擦除)的位置只能由迭代器
s指定<代码>常量迭代器不可接受
他举了一个例子,广泛使用static\u cast
来绕过这些限制,但他指出
…我展示的代码也可能无法编译,因为没有从常量迭代器
到迭代器
的可移植转换,即使使用静态转换
。即使是被称为
reinterpret\u cast
的语义大锤也无法完成这项工作
他总结说:
在C++98中,const_迭代器
s太麻烦了,几乎不值得麻烦
这些问题由C++11标准解决。正如在对您的问题的评论中提到的,本标准引入了cbegin
和cend
,它们返回const\u迭代器
,而不管容器本身是否为const
。而且,和被赋予了重载,使用常量迭代器
。这使得常量迭代器更容易使用。这本书有多旧?不确定cbegin和cend是什么时候引入的。@Robinson:它相当古老,从2001年开始……实际上,C++11支持和forconst\u iterator
@kyle get answering。const\u iterator
指定它不会修改它指向的对象,而不是容器不会被修改,但我想知道为什么他根本没有提到我认为存在const_iterator
的主要原因,以表示迭代器不会修改容器;任何完整的答案都应该引用迈尔斯在现代C++中的论点,即C++ 98、代码>康斯坦基