在他的有效STL一书的第26项中,Scott Meyers建议优先iterator
而不是const_iterator
。据我了解,他主要通过解释const_iterator
不适用于insert
或erase
等某些功能来证明这一点。
但这不是const_iterator
的全部意义,它不允许修改容器吗?也许更重要的是,它允许您在代码中表达这一意图。
默认情况下,他不应该建议您使用const_iterator
,只有在需要修改容器时才使用iterator
?
答案 0 :(得分:3)
他在书中所说的理由是:
•某些版本的插入和擦除需要迭代器。如果你想 调用这些函数,你将不得不生成迭代器。 const和反向迭代器不会做
•无法将const迭代器隐式转换为迭代器, 以及项27中描述的用于生成迭代器的技术 来自const_iterator既不普遍适用也不保证 要有效率。
但,非常重要,他继续说道:
不要误以为这意味着const迭代器是无用的 一般来说。他们不是。它们对算法非常有用, 因为算法通常不关心它们是什么类型的迭代器 与...合作。只要它们属于适当的类别。 const迭代器 对于许多容器成员函数也是可接受的。它' S 只有某种形式的插入和擦除是挑剔的。
因此,与往常一样,它在很大程度上取决于背景和情况。
答案 1 :(得分:3)
简短的回答是,由于C ++ 11标准的改进,当使用STL的最新实现时,Meyers 认为const_iterator
更可取。< / p>
在讨论他首先提出反const_iterator
建议并解释变化的原因之前,我需要澄清一个误解。你写道:
不是
const_iterator
的整点,它不允许修改容器吗?
这是一个明智的假设,但实际上这并不是iterator
的目的。正如迈耶斯在第三版 Effective C ++ 中所解释的那样(特别是在 C ++ 11之前编写):
声明
const
const
就像声明一个指针T* const
(即声明一个iterator
指针):const T*
是不允许的指向不同的东西,但它指向的东西可能会被修改。如果你想要一个指向无法修改的东西的迭代器(即const_iterator
指针的STL模拟),你需要一个const_iterator
[。]
简而言之,insert
无法防止修改容器,它可以防止修改包含的值。这就是为什么Meyers希望const_iterator
与erase
兼容:它不会修改容器中已存在的任何元素。
const
有点奇怪,因为它导致包含的元素被破坏,这是一个非erase
操作。但请注意,元素的析构函数不是通过迭代器本身调用的;迭代器只是API提供给指定项目的手段const_iterator
d。在语义上,iterator
应该能够实现此目的以及const_iterator
。
现在,关于 Effective STL 中的建议及其随后的撤消,我将在这个问题上解释并引用一些 Effective Modern C ++ 。在第13项中,&#34;首选iterator
到const_iterators
s&#34;,迈耶斯写道:
...在C ++ 98中,
const_iterator
只有半心半意的支持。创建它们并不容易,一旦你有了它,你可以使用它的方式是有限的.......没有简单的方法从非
const
容器中获取const_iterator
...一旦你有
iterator
s ...插入(和删除)的位置只能由const_iterator
指定。static_cast
是不可接受的。
他举了一个例子,广泛使用const_iterator
来解决这些限制,但指出,
...我所显示的代码也可能无法编译,因为没有
iterator
到static_cast
的可移植转换,甚至没有reinterpret_cast
1}}。即使是被称为const_iterator
的语义大锤也无法完成这项任务。
他总结道:
...
cbegin
在C ++ 98中遇到了很多麻烦,很少值得打扰。
这些问题由C ++ 11标准解决。正如对您的问题的评论中所提到的,此标准引入了cend
和const_iterator
,无论容器本身是否为const
,它都会返回const_iterator
。此外,insert
和erase
获得了const_iterator
的重载。这使得Any CPU
更容易使用。