-
list <int> a;
-
a.push_back(10);
-
a.push_back(15);
-
int* po;
-
list <int>::reverse_iterator iter=a.rbegin();
-
cout<<"value of iter point to:"<<*iter<<endl;
-
po=&(*iter);
-
a.push_back(9);
-
cout<<"value of iter point to:"<<*iter<<endl;
-
cout<<"value of po point to:"<<*po<<endl;
-
// Visual Studio 2008
-
output:
value of iter point to:15
value of iter point to:9
value of po point to:15
I didn't move iter ,and i think it should point to value of 15.But it has point to 9,after "push_back".Why?
I have read the book Jos and it says what you say it says (surprise surprise eh). My thinking and logic where along the write lines but I am definately glad I read the book and got the kinks sorted out.
evenstar, as to your last question in the same book you need to refer to section 5.3 Pointers into Arrays which says among other things: Taking a pointer to one element beyond the end of an array is guaranteed to work. and The result of taking the address of the element before the initial element is undefined and should be avoided. Now while a list may not be an array a vector is and they both use the same standard implementation of the reverse iterator (shown on page 557 of said book) so the reverse iterator must conform to the 2 quotes I gave. That is it can point into or 1 past the end of the "array" or at any element in the array.
In light of that having the reverse iterator point to 1 past the required element and returning (current - 1) keeps the logic and pointer arithmetic nice and simple.
10 2155
Read the second paragraph of this link. In short: your iterator isn't valid anymore after a (structural) change of the container.
kind regards,
Jos
Thanks very much for your help,but it is a list,not a vector.
@evenstar
Ah, silly me ... it looks like your rbegin() object is 'over active'; this shouldn't happen as far as I know; I'll give it some more thoughts; strange ...
kind regards,
Jos
Banfa 9,065
Expert Mod 8TB
I can tell you what the actual behaviour of the STL (in my implementation which is gcc 4.4.3) is, whether this is mandated or not by the standard I don't know.
By it's nature rbegin returns the same value as end (in the same way rend returns the same value as begin). That is it returns a pointer just passed the end of the list. When you dereference the iterator returned by rbegin the first thing is does is temporarily back-up the list 1 place and then return that value.
What happens is when you get the iterator it points to rbegin, the beginning of the reversed list. The effect of this in your small (and ill advised in my opinion) program is that when you perform the 3rd push_back the iterator remains pointing at the start of the reversed list (probably what you would expect to happen if you took the value of begin and then did a push_back).
You dereference the actual value and take a pointer to it and you get a pointer to a specific list item and that remains constant but your iterator constantly remains pointing at the start of the reversed list not the start of the reversed list at the time you requested the iterator value because it actually points past the end of the list. So when you push_back the iterator points to the new reversed list start where as you pointer remains pointing at the specific list entry you pointed it at.
"it actually points past the end of the list"?Oh, what has happened ?
@Banfa
I find your reasoning wobbly at best ;-) and I checked good ol' Bjarne for this: read page 444 (the C++ programming language 3rd edition) for a nice picture of where those iterators actually point to. Page 557 gives the answer (par. 19.2.5: Reverse Iterators). Because you can't actually point before the first element (see that picture) you have to keep track of a 'current' position. That 'current' position is one position beyond (in normal direction) the actual position. That way you prevent something from pointing before the first element (which is impossible). The 'current' position is the actual reverse iterator. Halfway page 557 you can see what actually happens; it's nifty ...
kind regards,
Jos
Banfa 9,065
Expert Mod 8TB
I'll have to look it up tomorrow as my copy of that book is at work were I use it :D
Oh,I got it ,because of "current-1".JosAH and Banfa,I thank you very much indeed,that's very kind of you.
The book also says:
"avoid access violations,current points to the element after the one the reverse_iterator refers to.This implies that * returns the value * (current-1) and..."
But how to access violations?The rend(one-before-the-beginning)element can stop it.So,i don't think uisng "current-1" is necessary.
Banfa 9,065
Expert Mod 8TB
I have read the book Jos and it says what you say it says (surprise surprise eh). My thinking and logic where along the write lines but I am definately glad I read the book and got the kinks sorted out.
evenstar, as to your last question in the same book you need to refer to section 5.3 Pointers into Arrays which says among other things: Taking a pointer to one element beyond the end of an array is guaranteed to work. and The result of taking the address of the element before the initial element is undefined and should be avoided. Now while a list may not be an array a vector is and they both use the same standard implementation of the reverse iterator (shown on page 557 of said book) so the reverse iterator must conform to the 2 quotes I gave. That is it can point into or 1 past the end of the "array" or at any element in the array.
In light of that having the reverse iterator point to 1 past the required element and returning (current - 1) keeps the logic and pointer arithmetic nice and simple.
I appreciate your help greatly,and no question now.I am so glad.
Sign in to post your reply or Sign up for a free account.
Similar topics
by: Grant Edwards |
last post by:
In an interview at http://acmqueue.com/modules.php?name=Content&pa=showpage&pid=273
Alan Kay said something I really liked, and I think it applies
equally well to Python as well as the languages...
|
by: Michael Klatt |
last post by:
I am trying to write an iterator for a std::set that allows the
iterator target to be modified. Here is some relvant code:
template <class Set> // Set is an instance of std::set<>
class...
|
by: nick |
last post by:
Hi,
I need to manage a "layered" collection of objects, where each layer
grows independently, e.g,
o--+--+--+--+--+ 1st layer
|
o 2nd layer (empty)
|
o--+--+--+ 3rd...
|
by: shawnk |
last post by:
I searched the net to see if other developers have been looking for a
writable iterator in C#. I found much discussion and thus this post.
Currently (C# 2) you can not pass ref and out arguments...
|
by: mailforpr |
last post by:
Hi.
Let me introduce an iterator to you, the so-called "Abstract Iterator"
I developed the other day.
I actually have no idea if there's another "Abstract Iterator" out
there, as I have never...
|
by: T.A. |
last post by:
I understand why it is not safe to inherit from STL containers, but I have
found (in SGI STL documentation) that for example bidirectional_iterator
class can be used to create your own iterator...
|
by: mailforpr |
last post by:
How do I do that?
The thing is, the only information I have about the iterator is the
iterator itself. No container it is belonging to or anything. Like
template<Iteratorvoid...
|
by: Steven D'Aprano |
last post by:
I thought that an iterator was any object that follows the iterator
protocol, that is, it has a next() method and an __iter__() method.
But I'm having problems writing a class that acts as an...
|
by: mkborregaard |
last post by:
Hi,
I have the weirdest problem, and I can not see what is going wrong.
I have made a 2d container class, and am implementing an iterator for that class. However, the ++ operator is behaving very...
|
by: Terry Reedy |
last post by:
Luis Zarrabeitia wrote:
Interesting observation. Iterators are intended for 'iterate through
once and discard' usages. To zip a long sequence with several short
sequences, either use...
|
by: Faith0G |
last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome former...
|
by: ryjfgjl |
last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
|
by: aa123db |
last post by:
Variable and constants
Use var or let for variables and const fror constants.
Var foo ='bar';
Let foo ='bar';const baz ='bar';
Functions
function $name$ ($parameters$) {
}
...
|
by: ryjfgjl |
last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
|
by: emmanuelkatto |
last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud.
Please let me know.
Thanks!
Emmanuel
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: Sonnysonu |
last post by:
This is the data of csv file
1 2 3
1 2 3
1 2 3
1 2 3
2 3
2 3
3
the lengths should be different i have to store the data by column-wise with in the specific length.
suppose the i have to...
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
| |