2010-07-25 133 views
2

Effective C++,第3项C++:使用常量与STL迭代器

/* 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适用,我曾经记得this article

基本上 '常量' 以下适用于任何 在它的左侧(不包括 ,如果没有任何其他 的情况,它适用于它的任何 直接右侧)。

当我第一次读到书中的第3项时,我预料它会在case1和case2中相反。

我应该将此案例视为例外吗?还是有一些更深层次的理解,我错过了?

回答

1

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

但是,您可以申报情况1这样的:

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

就像你可以指定const int xint const x

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

我看不出有什么特别的经验法则可以遵循 - 你的文章中的评论是正确的想法,你只需要学习如何将const_iterator作为const T*等等。

5

你可以认为它是作为如果迭代器是typedef ED就像这样:

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的工作方式。

8

该规则按照广告方式工作。

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

右侧的项目是iterator:迭代器是不可变的。你不能指定迭代器指向矢量中的不同项目,你不能增加它,它总是指向它初始化的项目。不过,您可以更改指向的项目。

这很少是所需的行为,这就是为什么存在const_iterator typedef。

std::vector<int>::const_iterator ci 

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

这里没有const关键字,所以你不能使用规则来弄清楚。对于这一个,你只需要了解什么const_iterator被记录下来。

+0

一个地方,我发现第一个案例是有用的保存搜索的输出,从'std :: find_if'说。 'const std :: vector :: iterator i = std :: find_if(...);'说我想记住搜索的结果,并且我不想无意中改变结果。 – SCFrench 2010-07-25 18:18:56

1

我认为const_iterator让你感到困惑。这是一个简单的typedefs的例子。

typedef int* Type; 
typedef const int* ConstType; 

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

const的情况下,1适用于迭代器,所以它使迭代器本身是常量。它对迭代器“指向”的项目没有任何影响。 (这就好比在T* const,当指针const,而不是指向的T

在案例2中,在const只是名字const_iterator的一部分,所以它不能真正推断出什么const有。这个班可能只有一个不好的名字,可能根本就没有任何固定的名字。但是,在这种情况下,const_iterator不允许修改其目标元素,因为它的定义与标准库中的类似。