注册 登录
LUPA开源社区 返回首页

fandaozhang的个人空间 http://www.lupaworld.com/?381944 [收藏] [复制] [分享] [RSS]

我的博客

C++的迭代器

热度 1已有 2459 次阅读2011-6-13 11:05 |系统分类:IT技术|

Iterators in C++

C++的迭代器

The C++ standard library provides iterators for the standard containers (for example, list, vector, deque, and so on) and a few other noncontainer classes. You can use an iterator to print the contents of, for example, a vector like this:

C++的标准库提供用于标准容器(listvectordeque)和一些非容器类的迭代器。

例如,对一个vector的操作:

vector<int> v;

// fill up v with data...

for (vector<int>::iterator it = v.begin();

     it != v.end(); ++it) {

   cout << *it << endl;

}

 

The variable it is the iterator. This use case illustrates how the iterator pattern requirements are implemented in C++.

it”就是一个迭代器。这个例子说明C++里迭代器模式的需求是如何实现的。

 

Obtain an iterator to the first element in a container by calling that container's begin member function.

把一个迭代器移动到容器的第一个元素通过调用成员函数:begin()

 

Advance an iterator to the next element with the pre- or post-increment operator, as in ++it or it++.

递增一个迭代器指向下一个元素,通过“-”“+”。例如:++it     it++

Get the value it refers to with the pointer dereference operator *, as in *it.

返回迭代器指向元素的值,通过“*”操作符,如:*it

 

Finally, you can see if an iterator is at the end of a range by comparing it to the iterator returned by the container's end member function, which returns an iterator that refers to one past the end of the elements.

最后,我们可以看到迭代器通过和成员函数:end()比较判断是否已经到了结尾。

 

This is why the continuation test for the for loop in the example above is it != v.end(). These one-past-the-end semantics are important in C++, so let's talk about that for a moment.

示例代码在循环里测试结束条件的代码是it != v.end()。这种one-past-the-end的语法在C++里是很重要的。

 

The iterator returned by a container's end member function represents a logical element that's one past the last element in a container, not the physical memory location that's just beyond the last element (which doesn't make sense for some kinds of data structures anyway).

通过容器的end成员函数返回迭代器,这是逻辑的最后一个元素而不是物理内存的最后(这对于有些数据结构来说并不是没有道理。)

 

You should never dereference it, because it is just a marker and holds nothing of value. The point of such a construct is to provide a logical end marker for a range, regardless of the context in which that range is used. Standard algorithms and all member functions that work with a range of iterators use this convention.

你不应该解引用它,因为它仅仅是一个标记而且没有携带任何值。它仅仅是提供一个区间的逻辑的结束标志,忽略你这个区间的使用上下文。使用迭代器的标准算法和成员函数都遵守这个约定。

 

 

This is why you can use standard algorithms, such as sort in <algorithm>, like this:

这就是为什么你可以使用在<algorithm>里的标准算法如下:

sort(v.begin(), v.end());

 

sort sorts everything in the range up to, but not including, the iterator supplied as its second argument.

Sort函数可以排序任何区间,除了迭代器作为第二个参数传递进去的情形。

 

You can see that C++ iterators permit the same operations as the iterator pattern requires, but not literally.

你会发现C++的迭代器有 “迭代器模式”的操作,但并不是完全有。

 

It's all there: move to the beginning, advance to the next element, get the referent, and test to see if you're at the end.

迭代器模式的要求是:移动到开始,递增到下一个元素,获取引用,判断是不是到结尾。

 

In addition, different categories of iterators support additional operations, such as moving backward with the decrement operators (--it or it--), or advancing forward or backward by a specified number of elements. I will explain iterator categories a little later.

另外,不同的迭代器支持不同的自增操作,比如:递减到前一个元素(--it it--),递增或递减通过一个指定的数字。我在后面要解释迭代器的分类。

 

The above example won't work if you are working with a const container though (it won't even compile). In this case, you need to use a const_iterator, which works just like the iterator type in the example above, except that when you dereference it, you get back a const object.

上面的例子吧可以在常量容器上工作,甚至不可以编译通过。在这个例子中,你需要使用const_iterator。就像上面的例子一样,除非你要解引用它,你取回一个常量对象。

 

Therefore, a function to print the contents of a const container might look like this:

因此,一个函数打印一个const的容器的元素,写法如下:

void printCont(const vector<int>& v) {

   for (vector<int>::const_iterator it = v.begin();

        it != v.end(); ++it) {

      cout << *it << endl;

   }

}

 

 

 

 

Incidentally, even if you aren't working with a const object, it is a good idea to use a const_iterator if you don't plan on modifying the elements in a container. This way, the compiler will keep you honest if you mistakenly try to modify an element.

顺便说一句,即使你不使用常量对象,但是当你不希望改变容器里的元素的时候,你使用const_iterator也是一个很好的选择。

 

There are a couple of important points to make here.

这里有几点比较重要。

 

First, note that the iterator and const_iterator types above are not part of the C++ language, they are just classes implemented in the standard library (just like the containers).

首先,注意迭代器和常量迭代器类型并不是C++的内置类型,他们仅仅是标准库的实现(就像是容器一样)

 

Second, the exact type of an iterator is specific to the container (or other object) it is being used with, which is why you have to declare it using a name that includes the container name, such as vector<int>::iterator.

其次,在使用的时候一个迭代器的类型是和特特定容器(或者是其他对象)绑定在一起的,这就是为什么你声明迭代器的时候要连着容器的名字,比如:

vector<int>::iterator

 

Furthermore, each standard library implementation is free to choose the specific type of a container's iterator types, so long as it exposes it to the user of a container using the names iterator and const_iterator.

而且,每个标准库的实现都是可以自由选择容器的迭代器类型,而且给容器的使用者的迭代器就是iteratorconst_iterator

 

This can be done with a public typedef. The actual type may be a pointer or a class whose structure and behavior are different from one standard library to another (though they must all support the specific behavior required by the standard).

这可以用typedef定义,在实际情况里,有可能是一个指针,一个数据结构的类而且,在不同的标准库还不一样( 虽然他们都满足指定的标准)(也就是说迭代器的实现因人而异)

 

 已同步至 fandaozhang的微博

刚表态过的朋友 (0 人)

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 注册
验证问答 换一个 验证码 换一个

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部