C++:将 const 与 STL 迭代器一起使用

发布于 2024-09-12 01:39:34 字数 744 浏览 5 评论 0原文

来自有效的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

随风而去 2024-09-19 01:39:34

该规则按照广告规定发挥作用。

const std::vector<int>::iterator i

紧邻右侧的项是迭代器:迭代器是不可变的。您不能将迭代器指定为指向向量中的不同项目,也不能递增它,它始终指向其初始化的项目。不过,您可以更改所指向的项目。

这很少是期望的行为,这就是 const_iterator typedef 存在的原因。

std::vector<int>::const_iterator ci

迭代器可以移动,但指向的项不能修改。这几乎总是您想要的——您想要迭代向量但无法修改其内容。

这里没有 const 关键字,因此您无法使用该规则来计算它。对于这个,您只需了解 const_iterator 记录的用途即可。

The rule works as advertised.

const std::vector<int>::iterator i

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.

std::vector<int>::const_iterator ci

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 what const_iterator is documented to do.

好菇凉咱不稀罕他 2024-09-19 01:39:34

您可以将其视为迭代器的 typedef,如下所示:

typedef T* iterator;
typedef const T* const_iterator;

当您将 const 添加到其中任何一个时,它会应用于顶层 em>,即指向指针本身,而不是指向所指向的对象,因此以下等价关系成立:

const iterator it; // is the same as:
T* const it;

const const_iterator it; // is the same as:
const T* const it;

它们不是例外;这就是所有 typedef 的工作原理。

You can think of it being as if the iterators were typedefed like so:

typedef T* iterator;
typedef const T* const_iterator;

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:

const iterator it; // is the same as:
T* const it;

const const_iterator it; // is the same as:
const T* const it;

They are not an exception; this is how all typedefs work.

孤千羽 2024-09-19 01:39:34

引用的规则对于 const 关键字来说绝对正确。但是,在处理迭代器时,const_iterator 类仅仅是这样命名的(它同样可以是 readonly_iterator),因此关于 const 关键字的规则不适用。

不过,您可以像这样声明情况 1:

std::vector<int>::iterator const i

就像您可以指定 const int xint const x 一样。

迭代器指向的类型也在其容器的模板参数中指定,因此顺序与声明普通变量不同。

我看不出这里有任何特定的经验法则可以遵循 - 您帖子中的评论是正确的想法,您只需要学会将 const_iterator 视为 const T*等等。

The rule quoted is absolutely true of the const keyword. However, when dealing with iterators, the const_iterator class is merely named so (it could equally be readonly_iterator), so the rule about the const keyword does not apply.

You can however declare case 1 like this:

std::vector<int>::iterator const i

just like you can specify either const int x or int 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 as const T* and so on.

眼前雾蒙蒙 2024-09-19 01:39:34

我认为 const_iterator 让您感到困惑。这是一个具有更简单 typedef 的示例。

typedef int* Type;
typedef const int* ConstType;

int main() {
  const Type a; // int * const
  ConstType b; // const int *
}

I think that the const_iterator is confusing you. Here is an example with simpler typedefs.

typedef int* Type;
typedef const int* ConstType;

int main() {
  const Type a; // int * const
  ConstType b; // const int *
}
苄①跕圉湢 2024-09-19 01:39:34

情况 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 in T* const, where the pointer is const, not the pointed-to T)

In case 2, the const is just part of the name const_iterator, so it can't really be deduced what is const there. The class could just have a bad name and there could be nothing const about it at all. In this case however, the const_iterator doesn't allow modification of it's target element, because it is defined like that in the standard library.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文