Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么Scott Meyers建议选择“迭代器”而不是“常量迭代器”`_C++_Stl_Iterator - Fatal编程技术网

C++ 为什么Scott Meyers建议选择“迭代器”而不是“常量迭代器”`

C++ 为什么Scott Meyers建议选择“迭代器”而不是“常量迭代器”`,c++,stl,iterator,C++,Stl,Iterator,在《有效STL》一书的第26项中,Scott Meyers建议首选迭代器,而不是常量迭代器。据我所知,他主要通过解释const\u迭代器不能与insert或erase等特定函数一起工作来证明这一点 但是常量迭代器不允许修改容器,这不是它的全部要点吗?也许更重要的是,它允许您在代码中表达这一意图 他是否应该建议默认使用const\u迭代器,并且仅当您需要修改容器时,才使用iterator 他在书中说的原因是: •某些版本的insert和erase需要迭代器。如果你想 调用这些函数时,必须生成迭代器

在《有效STL》一书的第26项中,Scott Meyers建议首选
迭代器
,而不是
常量迭代器
。据我所知,他主要通过解释
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支持和for
const\u iterator
@kyle get answering。
const\u iterator
指定它不会修改它指向的对象,而不是容器不会被修改,但我想知道为什么他根本没有提到我认为存在
const_iterator
的主要原因,以表示迭代器不会修改容器;任何完整的答案都应该引用迈尔斯在现代C++中的论点,即C++ 98、代码>康斯坦基