Why do I have to dereference my vector iterator? What does it mean?

I wrote this code to test:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

#include <iostream>
#include <string>
#include <vector>

using namespace std;

struct Person {
string name;
int age;
};

int main()
{
// Populate some people and put them into a vector.

Person p1, p2, p3;
vector<Person> ListOfPeople;

p1.name = "Richard";
p2.name = "Mike";
p3.name = "Cheryl";

p1.age = 12;
p2.age = 13;
p3.age = 14;

ListOfPeople.push_back(p1);
ListOfPeople.push_back(p2);
ListOfPeople.push_back(p3);

vector<Person>::const_iterator citer = ListOfPeople.begin();

while ( citer != ListOfPeople.end() )
{
cout << (*citer).name << " is " << citer->age << " years old." << endl;
++citer;
}

return 0;
}


A clean version can be found at http://codepad.org/hAumqzNB with the associated output.

I know this has to do with pointers. I taught myself C++ once before using online tutorials but this book hasnt gone into pointers though it has covered references. This is one thing I never really understood about the language.

My questions:

Why do I have to deference this to make it work?
What exactly does dereferencing normally do?
Why on other sites do they say pointers are a type of iterator?
Lastly, object->member just a synonym of (*object).member and nothing more?

Edit: the book says derefencing gives an lvalue. Which i understand is a nontemporary object. So when you use an iterator does it act as a reference to the vector? Because I know you need lvalues to access data because of scoping issues. So does this essentially make a copy of the object in memory for the purpose of printing to the screen? aka an lvalue?

Sorry if I don't understand properly, its why im here :/

Thanks in advance for all your help!

Senjai
http://cplusplus.com/doc/tutorial/pointers/
http://en.wikipedia.org/wiki/Value_%28computer_science%29

An l-value is simply something containing a value that can be changed.
Because iterators are a generalization of pointers.
citer holds the address of the vectors elements, think of it like so:

1.
the vectors stores the elements:
P1  P2  P3

the iterator points to the address of these elements, so the elements become
bg2003 bg2005 bg2007
. You need to defreference the pointer so that it shows the data it points to, and not the address.

2.
a pointer stores the address of the data it points to, the symbol * grabs the value the pointer points to. Ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>

int main()
{
    int Fred = 42; //fred equals 42
    int * x; //create a pointer
    x = &Fred; //each now have the same address
    //because x POINTS to fred
    std::cout << "Address of Fred: " << &Fred 
    << "Address of pointer: " << x;
    std::cout << "Value of Fred " << Fred
    << "Value of pointer " << *x; //grabs the value x
    //POINTS to, not the address
}


4. I personally use -> because of its look and its simplicity.
Last edited on
this book hasnt gone into pointers though it has covered references.

Good book. References are much more fundamental.

the book says derefencing gives an lvalue

Good book. That's exactly what it does.

Why do I have to deference this to make it work?

You want to access the object that is referenced by the iterator. To do exactly that, you dereference.

What exactly does dereferencing normally do?

It accesses the object that's referenced by the iterator or pointer. There's simply no other way to get to that object.

Why on other sites do they say pointers are a type of iterator?

Because it is true. A raw pointer to an element of a C array or one-past-the-end of a C array is a random access iterator. Also, vector iterators, string iterators, and C++ array iterators are implemented as raw pointers (except in some debug mode builds)

Lastly, object->member just a synonym of (*object).member and nothing more?

It is true for built-in meaning of operator-> and operator*. Those operators may be redefined, but they are usually redefined in the way that maintains this identity.

an lvalue Which i understand is a nontemporary object.

No. Objects are *never* l/r/x-values. That's an expression category.. but it will take a while to explain. For simplicity, imagine the book said "reference" instead. Dereferencing an iterator produces a reference to the object that iterator is pointing to.

So when you use an iterator does it act as a reference to the vector?

It holds a reference to an element of the vector.

Because I know you need lvalues to access data because of scoping issues.

This doesn't quite make sense. You can access members of an rvalue just the same.

So does this essentially make a copy of the object in memory for the purpose of printing to the screen? aka an lvalue?

No, this *essentially* gives you the reference to the pointed-to Person (which is not an object, and not a copy of an object, it's an alias, or an access path to reach an existing object. A read-only access path in your case, since you dereferenced a const_iterator. )Then you use a member access operator to create a reference to the member (name or age) of the pointed-to Person. Then you pass that reference to operator<< for output. No copies involved.
Last edited on
Thank all of you for clearing this up. I understand completely.

FYI the book I'm using is called Accelerated C++, the question stems from chapter five.

Thank you especially to cubbi for taking so much time to answer all my questions!
@Cubbi
this book hasnt gone into pointers though it has covered references.

Good book. References are much more fundamental.


I would not say that it is a good book because iterators as a generalization of pointers are better understandable after studing pointers. And this thread demonstartes this idea. If he would know pointers he would not ask his questions.:)
The book I'm using was recommended by a few people. It covers vector before arrays even.

When I learnt C++ the first time around pointers confused the hell out of me. My confusion here stems from understanding exactly what container<container-type>::iterator IS, i didn't know it was explicitly a pointer or to what level.

Up until I learnt this, including use the begin() and end() members everything worked behind the scenes. That's why I asked the question.

EDIT: Actually to be fair, it has covered pass by reference. Not really exactly what the reference is persay. It distinguished the difference between Pass by Value and Pass by Reference. Stating that type& name essentially becomes a synonym for name and changes within this scope will affect the variable outside the scope. Something like that at least.
Last edited on
@vlad iterators are a generalization of only one use case for pointers - the raw-pointers-used-as-Random-Access-Iterators pointers, and that use case doesn't even come up in C++ unless you're working with C-style arrays. It's only helpful for those who had prior C experience and had to deal with that intimately.

covers vector before arrays even
.
So was it Accelerated or PPP? (although in truth, all C++ textbooks should do that. Vectors are the default containers in C++, and should be explained first)... edit: oh, right, Accelerated.

Not really exactly what the reference is persay [...] type& name essentially becomes a synonym for name

That's exactly what the reference is.
Last edited on
@Cubbi
@vlad iterators are a generalization of only one use case for pointers - the raw-pointers-used-as-Random-Access-Iterators pointers, and that use case doesn't even come up in C++ unless you're working with C-style arrays. It's only helpful for those who had prior C experience and had to deal with that intimately.


In my opinion you are wrong. I would like point out that vectors and strings have random access iterators.
But even if do not speak about vectorsand strings the phrase of that iterators are a generalization of pointers means that they try imitate behavior of pointers but of course they can be weaker than pointers. So to understand iterators one should understand pointers, their syntactic and symantic using.
Last edited on
@vlad pointers do a LOT more than act as random-access iterators into C arrays. They handle objects with dynamic lifetime, provide aggregation, optional types, rebindable references, polymorphic containers, type erasure, delegates, and many other things that are actually *useful* in C++. It is entirely backwards to learn all about pointers, including all the C array nonsense (what else? C strings??), before learning about iterators for the first time.
You're not teaching history, you're teaching a language.
Topic archived. No new replies allowed.