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

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



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

Iterators in 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:



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++.



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



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.



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.



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).



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:


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


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



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.



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


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.



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).



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.




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.



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 个评论)


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

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