- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
在他的 Effective STL 一书的第 26 项中,Scott Meyers 建议优先使用 iterator
而不是 const_iterator
。据我了解,他主要通过解释 const_iterator
不适用于某些函数,如 insert
或 erase
来证明这一点。
但这不是 const_iterator
的全部意义,它不允许修改容器吗?也许更重要的是,它允许您在代码中表达这种意图。
难道他不应该建议默认使用 const_iterator
并且只有在需要修改容器时才使用 iterator
吗?
最佳答案
简短的回答是,由于 C++11 中的改进,Meyers 确实在使用 STL 的最新实现时考虑了 const_iterator
标准。
不过,在首先讨论他给出反const_iterator
建议的原因并解释发生了什么变化之前,我需要澄清一个误解。你写:
isn't that the whole point of a
const_iterator
, that it does not allow modifying the container?
这是一个合理的假设,但实际上这并不完全是 const_iterator
的目的。正如 Meyers 在 Effective C++ 第三版中解释的那样(值得注意的是,在 C++11 之前):
Declaring an
iterator
const
is like declaring a pointerconst
(i.e., declaring aT* const
pointer): theiterator
isn't allowed to point to something different, but the thing it points to may be modified. If you want an iterator that points to something that can't be modified (i.e., the STL analogue of aconst T*
pointer), you want aconst_iterator
[.]
简而言之,const_iterator
不防止修改容器,它防止修改包含的值。这就是 Meyers 期望 insert
与 const_iterator
兼容的原因:它不会修改容器中已经存在的任何元素。
erase
有点奇怪,因为它导致包含的元素被销毁,这是一个非const
操作。但请注意,元素的析构函数不是通过迭代器本身调用的;迭代器只是 API 提供的方法,用于指定要删除
的项目。从语义上讲,const_iterator
应该和 iterator
一样能够达到这个目的。
现在,关于 Effective STL 中的建议及其随后的撤回,我将解释并引用 Effective Modern C++ 中的一些内容。在第 13 项“更喜欢 const_iterator
而不是 iterator
”中,Meyers 写道:
...in C++98,
const_iterators
had only halfhearted support. It wasn't that easy to create them, and once you had one, the ways you could use it were limited.......there was no simple way to get a
const_iterator
from a non-const
container...Once you had the
const_iterator
s...locations for insertions (and erasures) could be specified only byiterator
s.const_iterator
s weren't acceptable.
他给出了一个广泛使用 static_cast
来绕过这些限制的例子,但指出,
...the code I've shown might not compile, either, because there's no portable conversion from a
const_iterator
to aniterator
, not even with astatic_cast
. Even the semantic sledgehammer known asreinterpret_cast
can't do the job.
他总结道:
...
const_iterator
s were so much trouble in C++98, they were rarely worth the bother.
C++11 标准解决了这些问题。正如在对您的问题的评论中提到的,该标准引入了 cbegin
和 cend
,无论容器本身是否为 ,它们都会返回
。另外,const_iterator
>常数insert
和 erase
被赋予采用 const_iterator
的重载。这使得 const_iterator
更易于使用。
关于c++ - 为什么 Scott Meyers 建议更喜欢 `iterator` 而不是 `const_iterator`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45824885/
我正在尝试表达以下内容: 给定一个矩阵和两个索引增量,返回矩阵中所有数字的四倍体:沿行,列或对角线的四倍体。 use std::iter::Iterator; use std::iter::Peeka
假设我们有以下类组成角色 Iterable : class Word-Char does Iterable { has @.words; method !pairize($item)
我编写了一个 ADT 排序二叉树,其功能如下: public Iterator getInorderIterator(){ return new InorderIterator(); } 有效
在包装(内部)迭代器时,通常必须将 __iter__ 方法重新路由到底层可迭代对象。考虑以下示例: class FancyNewClass(collections.Iterable): def
尽管如此,我遍历了以下 NSSet , NSMutableArray , NSFastEnumeration文档,我找不到下面提到的场景的令人满意的来源: 此处,NSMutableArray、NSAr
我发现在 Python 中 collections.Iterable 和 typing.Iterable 都可以用于类型注释和检查对象是否可迭代,即 >isinstance(obj, collecti
我想拆分实现 Iterator 的对象的输出分为两个实现 Iterator 的对象和 Iterator .由于其中一个输出的迭代次数可能比另一个多,因此我需要缓冲 Iterator 的输出。 (因为我
我正在尝试用 Rust 编写一个简单的迭代器: #[derive(Debug)] pub struct StackVec { storage: &'a mut [T], len: us
什么意思: Separator.Iterator.Element == Self.Iterator.Element.Iterator.Element 在this (Swift 标准库)swift 实例
调用 anIterable.iterator() 会返回新的迭代器还是现有的迭代器?它依赖于 Iterable 的实现吗? 更具体地说,以下代码是否按预期工作(即内部循环将从头开始迭代)? for (
我正在尝试转换 &str 的矢量对成一个 HashMap使用以下代码片段: use std::collections::HashMap; fn main() { let pairs = vec!(
这将使安全地迭代同一元素两次成为可能,或者为在项目类型中迭代的全局事物保持某种状态。 类似于: trait IterShort where Self: Borrow, { type I
我在 String 的字符上使用迭代器: pub fn is_yelling(message: &str) -> bool { let letters = message.chars().fi
这将使安全地迭代同一元素两次成为可能,或者为在项目类型中迭代的全局事物保持某种状态。 类似于: trait IterShort where Self: Borrow, { type I
要在 Rust 中实现迭代器,我们只需要实现 next 方法,如 in the documentation 所解释的那样.但是,Iterator 特征 has many more methods .
我正在为多个结构实现 Iterator 特性并遇到了一些问题。为什么为 Rows 实现 Iterator 显示错误?这是一个链接:link to playground 基本上为什么这不起作用? str
我将集合转储到磁盘上。当请求时,应该检索这些集合(没问题)和 iterator应该为它构建返回对检索到的值的引用。 iterator之后被丢弃了,我不再需要收藏了。我也希望它被删除。 到目前为止我尝试
我正在尝试为实现特征的结构实现默认迭代器。我的特征称为 DataRow,代表一行表格单元格,如下所示: pub trait DataRow { // Gets a cell by index
Rust 中是否有提供 iter() 的 Trait方法?我只找到了特征 IntoIterator ,供应into_iter() . 这里要明确一点:我不想要 Iterator特性,提供 next()
我想在迭代器上定义一个 .unique() 方法,使我能够在没有重复的情况下进行迭代。 use std::collections::HashSet; struct UniqueState {
我是一名优秀的程序员,十分优秀!