C++:将 const 与 STL 迭代器一起使用
来自有效的 C++,第 3 项
/* case1 */ const std::vector<int>::iterator i // i acts like a T* const
/* case2 */ std::vector<int>::const_iterator ci // ci acts like a const T*
为了记住 const
如何应用,我曾经记住 本文
基本上“const”适用于任何事物 位于其紧邻左侧(除了 如果那里没有任何东西 它适用于它的任何情况 立即右侧)。
当我第一次读到书中的第3条时,我预计case1和case2的情况是相反的。
我应该将这种情况视为例外吗?还是我缺少一些更深层次的理解?
From Effective C++, Item 3
/* case1 */ const std::vector<int>::iterator i // i acts like a T* const
/* case2 */ std::vector<int>::const_iterator ci // ci acts like a const T*
To remember how const
applies, I used to remember the following from this article
Basically ‘const’ applies to whatever
is on its immediate left (other than
if there is nothing there in which
case it applies to whatever is its
immediate right).
When I read the Item 3 in the book first, I expected it to be the other way round in case1 and case2.
Should I treat this case as an exception? Or is there some deeper level understanding that I am missing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
该规则按照广告规定发挥作用。
紧邻右侧的项是迭代器:迭代器是不可变的。您不能将迭代器指定为指向向量中的不同项目,也不能递增它,它始终指向其初始化的项目。不过,您可以更改所指向的项目。
这很少是期望的行为,这就是
const_iterator
typedef 存在的原因。迭代器可以移动,但指向的项不能修改。这几乎总是您想要的——您想要迭代向量但无法修改其内容。
这里没有
const
关键字,因此您无法使用该规则来计算它。对于这个,您只需了解const_iterator
记录的用途即可。The rule works as advertised.
The item on the immediate right is
iterator
: the iterator is immutable. You cannot assign the iterator to point to different items in the vector, you cannot increment it, it always points to the item it is initialized to. You can change the item being pointed to, though.This is rarely the desired behavior, which is why the
const_iterator
typedef exists.The iterator can be moved around, but the item pointed to cannot be modified. This is pretty much always what you want--you want to iterate over a vector but not be able to modify its contents.
There's no
const
keyword here so you can't use the rule to figure it out. For this one you just have to understand whatconst_iterator
is documented to do.您可以将其视为迭代器的 typedef,如下所示:
当您将
const
添加到其中任何一个时,它会应用于顶层 em>,即指向指针本身,而不是指向所指向的对象,因此以下等价关系成立:它们不是例外;这就是所有
typedef
的工作原理。You can think of it being as if the iterators were
typedef
ed like so:When you add
const
to either of these, it applies at the top level, that is, to the pointer itself, not to the object pointed to, so the following equivalencies hold:They are not an exception; this is how all
typedef
s work.引用的规则对于
const
关键字来说绝对正确。但是,在处理迭代器时,const_iterator
类仅仅是这样命名的(它同样可以是readonly_iterator
),因此关于const
关键字的规则不适用。不过,您可以像这样声明情况 1:
就像您可以指定
const int x
或int const x
一样。迭代器指向的类型也在其容器的模板参数中指定,因此顺序与声明普通变量不同。
我看不出这里有任何特定的经验法则可以遵循 - 您帖子中的评论是正确的想法,您只需要学会将
const_iterator
视为const T*等等。
The rule quoted is absolutely true of the
const
keyword. However, when dealing with iterators, theconst_iterator
class is merely named so (it could equally bereadonly_iterator
), so the rule about theconst
keyword does not apply.You can however declare case 1 like this:
just like you can specify either
const int x
orint const x
.The type an iterator points to is also specified in the template parameter of its container, so the ordering is different to declaring ordinary variables.
I can't see that there's any particular rule of thumb to follow here - the comments in your post are the right idea, you just need to learn to treat
const_iterator
asconst T*
and so on.我认为 const_iterator 让您感到困惑。这是一个具有更简单 typedef 的示例。
I think that the const_iterator is confusing you. Here is an example with simpler typedefs.
情况 1 中的 const 适用于迭代器,因此它使迭代器本身成为 const。它对迭代器“指向”的项目没有任何影响。 (这就像在
T* const
中一样,其中指针是const
,而不是指向的T
)在情况 2 中,
const
只是名称const_iterator
的一部分,因此无法真正推断出其中的const
是什么。这个类可能只是有一个坏名声,而且根本没有什么不好的地方。但在这种情况下,const_iterator 不允许修改其目标元素,因为它的定义与标准库中的定义类似。The
const
in case 1 applies to the iterator, so it makes the iterator itself const. It doesn't have any effect on the item the iterator is "pointing to". (This is like inT* const
, where the pointer isconst
, not the pointed-toT
)In case 2, the
const
is just part of the nameconst_iterator
, so it can't really be deduced what isconst
there. The class could just have a bad name and there could be nothing const about it at all. In this case however, theconst_iterator
doesn't allow modification of it's target element, because it is defined like that in the standard library.