Dollarslice
Dollarslice

Reputation: 10284

why can't I dereference an iterator?

If I have a vector of objects (plain objects, not pointers or references), why can't I do this?

Object* object;

object = vectorOfObjects.end();

or

object = &vectorOfObjects.end();

or

object = &(*vectorOfObjects.end());

also the same question if 'object' was a reference.

Upvotes: 7

Views: 44933

Answers (4)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726479

This is because by convention end does not point to a valid location in the container: it sits at a location one past the end of the container, so dereferencing it is illegal.

The situation with begin() is different: you can dereference it when v.begin() != v.end() (i.e. when the container is not empty):

object = *vectorOfObjects.begin();

If you need to access the last element, you can do this:

vector<object>::const_iterator i = vectorOfObjects.end();
i--;
cout << *i << endl; // Prints the last element of the container

Again, this works only when your vector contains at least one element.

Upvotes: 3

Stack Overflow is garbage
Stack Overflow is garbage

Reputation: 247899

They are three separate errors:

object = vectorOfObjects.end();

won't work because end() returns a an iterator, and object is a pointer. Those are generally distinct types (A vector can use raw pointers as iterators, but not all implementations do it. Other containers require special iterator types).

object = &vectorOfObjects.end();

doesn't work because you take the address of the returned iterator. That is, you get a pointer to an iterator, rather than a pointer to an Object.

object = &(*vectorOfObjects.end());

doesn't work because the end iterator doesn't point to a valid element. It points one past the end of the sequence. And so, it can't be dereferenced. You can dereference the last element in the sequence (which would be --vectorOfObjects.end()), but not an iterator pointing past the end.

Finally, the underlying problem/confusion might be that you think an iterator can be converted to a pointer. In general, it can't. If your container is a vector, you're guaranteed that elements are allocated contiguously, like in an array, and so a pointer will work. But for, say, a list, a pointer to an element is useless. It doesn't give you any way to reach the next element.

Upvotes: 21

msgmash.com
msgmash.com

Reputation: 1035

Object* means a pointer to an Object, where a pointer is a memory address. But the .end() method returns an Iterator, which is an object itself, not a memory address.

Upvotes: -1

Luchian Grigore
Luchian Grigore

Reputation: 258558

Because .end() returns an iterator, not an Object, which isn't even a valid member of the vector.

Even using begin(), which returns a valid object, you'd need the following:

The correct way would be:

std::vector<Object> vec;
std::vector<Object>::iterator it;
//....
it = vec.begin();
Object o = *it;

Upvotes: 7

Related Questions