2

来自Effective 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 会相反。

我应该将这种情况视为例外吗?还是我缺少一些更深层次的理解?

4

5 回答 5

8

该规则按广告宣传。

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

右边的项目是iterator:迭代器是不可变的。您不能将迭代器分配为指向向量中的不同项目,也不能递增它,它始终指向它被初始化的项目。不过,您可以更改指向的项目。

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

std::vector<int>::const_iterator ci

迭代器可以移动,但指向的项目不能修改。这几乎总是你想要的——你想迭代一个向量但不能修改它的内容。

这里没有const关键字,所以你不能使用规则来弄清楚。对于这一点,您只需要了解const_iterator记录在案的内容即可。

于 2010-07-25T18:09:55.243 回答
5

你可以把它想象成迭代器是typedef这样编辑的:

typedef T* iterator;
typedef const T* const_iterator;

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

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

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

他们也不例外。这就是所有typedef工作的方式。

于 2010-07-25T18:09:46.530 回答
1

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

typedef int* Type;
typedef const int* ConstType;

int main() {
  const Type a; // int * const
  ConstType b; // const int *
}
于 2010-07-25T18:11:56.727 回答
1

引用的规则绝对适用于const关键字。但是,在处理迭代器时,const_iterator类只是命名为 so(它也可以是readonly_iterator),因此关于const关键字的规则不适用。

但是,您可以像这样声明案例 1:

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

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

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

我看不出这里有什么特别的经验法则要遵循——你帖子中的评论是正确的想法,你只需要学会对待const_iteratorconst T*等等。

于 2010-07-25T18:08:45.807 回答
0

in case 1 适用于迭代器,因此const它使迭代器本身为 const。它对迭代器“指向”的项目没有任何影响。(这就像 in T* const,指针所在的位置const,而不是指向的位置T

在情况 2 中, theconst只是 name 的一部分const_iterator,因此无法真正推断出const其中的内容。该类可能只是有一个坏名字,而且根本就没有 const 。然而,在这种情况下,const_iterator不允许修改它的目标元素,因为它是在标准库中定义的。

于 2010-07-25T18:15:27.413 回答