简体   繁体   中英

Questions about C++ iterators

In C++, why can't we use '>' or '<' to compare InputIterators, ForwardIterators and BidirectionalIterators? However, we can compare RandomAccessIterators with '>' or '<', for example std::vector. What is the reason behind this?

Also, why can't we cout iterators' content? such as "cout << itr << endl;" wouldn't work. What is the reason behind this? Iterators are a lot like pointers, but we can cout pointers but not iterators, why?

In general, what is the intrinsic difference between iterators and pointers? I used to think they are similar, but I guess I have to understand this in order to get to the next level of understanding c++.

Question#2: Thank you all for awesome answers. I have one more question in regards to iterators. Why c++ prints out something like "50397953" when the iterator goes out of bounds? Shouldn't it be printing something like NULL or '\\0' ?

std::list<T> has bidirectional iterators and it doesn't make any sense to require them to be comparable. It's not even clear how it would be possible to implement std::list<T> in order to be compliant with such a requirement. However, since random access iterators support subtraction, it is obvious that we can compare them.

Why can't we print the value of an iterator? In general, it's up to the author whether to support such an operation. Many iterators are basically just implemented as pointers or wrappers around pointers---providing operator<< for them wouldn't give the user any benefit they couldn't get by simply printing out the address of the object pointed to.

As for the difference between iterators and pointers, pointers to objects are a specific kind of random access iterator, but iterators can also be of class type so long as they satisfy the iterator requirements.

There's both a rigid, formal explanation, and a practical one.

The rigid, formal explanation

Because that's how it's specified in C++.

The practical explanation

A vector is always stored in contiguous memory, by definition. An iterator is, more or less a pointer. Therefore, by comparing the actual underlying memory addresses it is possible to define which pointer is "less" or "greater" than the other pointer.

On the other hand, each element in a list, or a set, could be stored anywhere. Each element is instantiated independently. An iterator for one particular element in the list could be referencing a numerically lesser memory location than a different iterator for another element in the same list, but the actual element could be after the other element, in the actual list. Given two iterators in a list it cannot be immediately determined which one is closer to the beginning or to the end of the list. Note that inserting and removing elements in a list does not invalidate existing list iterators, because each element in the list is instantiated independently.

The practical reason why you cannot use iterators with operator<< on a std::ostream is because, of course, this overload is not defined. Note that you can always do the following, instead:

cout << &*itr << endl;

This will format the actual memory address of the referenced element. But this is of dubious use anyway. It's mostly meaningless.

I will not answer the first part of your question because I agree with what had been said, but I will answer you the other two parts adding some details. I am starting from the easiest part to explain.

In general, what is the intrinsic difference between iterators and pointers? I used to think they are similar, but I guess I have to understand this in order to get to the next level of understanding c++.

Iterators are generalization of pointers.

You can also look at that iterator implementation on github

Also, why can't we cout iterators' content? such as "cout << itr << endl;" wouldn't work. What is the reason behind this? Iterators are a lot like pointers, but we can cout pointers but not iterators, why?

So, what is happening inside, as I understand, is that iterator is a class which has a field storing a pointer to an item. The '*' operator is overwritten and returns the value that is stored at the pointers address.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM