Problem with pointers and iterators

B

BCC

Hi, if I have the following code:
class MyObject
{
public:
MyObject() {};
~MyObject() {};

int x;
}

class MyObjectList : public std::vector<MyObject> {};

void Foo(MyObject* obj)
{
// Do something with obj->x
}

If I loop through it like this:

MyObjectList list;
// stuff list with objects

MyObjectList::iterator it;
for (it = list.begin(); it != list.end(); ++it) {
// I used to be able to do this:
MyObject* p_obj = it;
Foo(p_obj);

// Or this
Foo(it);
}

But now the error I get is 'cannot convert parameter 1 from
'std::vector<_Ty>::iterator' to 'MyObject *'

This is after migrating a project from vc6.0 to vc7.1, but I think that
the issue lies with the language standards(?). So why does this happen
now, and how do I resolve it?

Thanks,
Bryan
 
V

Victor Bazarov

BCC said:
Hi, if I have the following code:
class MyObject
{
public:
MyObject() {};
~MyObject() {};

int x;
}

class MyObjectList : public std::vector<MyObject> {};

void Foo(MyObject* obj)
{
// Do something with obj->x
}

If I loop through it like this:

MyObjectList list;
// stuff list with objects

MyObjectList::iterator it;
for (it = list.begin(); it != list.end(); ++it) {
// I used to be able to do this:
MyObject* p_obj = it;
Foo(p_obj);

// Or this
Foo(it);
}

But now the error I get is 'cannot convert parameter 1 from
'std::vector<_Ty>::iterator' to 'MyObject *'

This is after migrating a project from vc6.0 to vc7.1, but I think that
the issue lies with the language standards(?). So why does this happen
now, and how do I resolve it?

An iterator is not a pointer. If you need to convert the iterator value
into a pointer to an object behind the iterator, you need to dereference
it first and then take the address:

MyObject* p_obj = &*it;

V
 
B

BCC

Victor said:
An iterator is not a pointer. If you need to convert the iterator value
into a pointer to an object behind the iterator, you need to dereference
it first and then take the address:

MyObject* p_obj = &*it;

V

I knew that an iterator was not a pointer, but I see that I was sloppy
and vc6.0 let me get away with it. Wonder what changed between the two
versions...

Thanks!
Bryan
 
E

E. Robert Tisdale

BCC said:
Hi, if I have the following code:

class MyObject {
public:
MyObject(void) { };
~MyObject(void) { };
private:
int x;
};

class MyObjectList: public std::vector<MyObject> { };

void Foo(MyObject* obj) {

// Do something with obj->x
}

If I loop through it like this:

MyObjectList list;
// stuff list with objects

MyObjectList::iterator it;
for (it = list.begin(); it != list.end(); ++it) {
// I used to be able to do this:
//MyObject* p_obj = it;

MyObject* p_obj = &(*it);
Foo(p_obj);

// Or this
Foo(it);
}

But now the error I get is 'cannot convert parameter 1 from
'std::vector<_Ty>::iterator' to 'MyObject *'

This is after migrating a project from vc6.0 to vc7.1,
but I think that the issue lies with the language standards(?).
So why does this happen now, and how do I resolve it?

The standard specifies that
`*it' is a reference to an object of type MyObject
but `it' is not necesaarily a pointer to that object.
 
R

Ron Natalie

BCC said:
I knew that an iterator was not a pointer, but I see that I was sloppy
and vc6.0 let me get away with it. Wonder what changed between the two
versions...

An implmenetation can implement vector::iterator as a pointer if it wants.
It will work fine. However, it can also impemenet it as a class (most likely
containing a pointer). The advantage of the latter is that it avoids
bogus conversions of the iterator to other pointers.
 
V

Victor Bazarov

BCC said:
[...]
I knew that an iterator was not a pointer, but I see that I was sloppy
and vc6.0 let me get away with it. Wonder what changed between the two
versions...

The implementation of the Standard library, apparently.

To make sure you don't rely on your compiler and library implementation
details in your project I strongly recommend you to use more than one
compiler at a time. Of course some code you write will have to use
platform-specific elements, like OS calls and GUI, but if you isolate
those in a particular location, the rest of the code can easily be
compiled with another compiler.

V
 
P

Peter Koch Larsen

Hi BCC

As others have pointed out, it is not necessarily a pointer so using it as
one is illegal (use &*it).
I will add that your Foo function looks odd. If Foo expects a pointer to a
valid Foo object, Foo should use a call by reference (void Foo(MyObject&)),
and if Foo only needs to manipulate obj->x, Foo should actually expect an
object of that type - and not a MyObject.
[snip]
/Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top