Using an iterator to remove an item from a STL list

J

Jonathan

Hi. I'm having trouble figuring out what I should be doing here.

I'm trying to remove an object from a list.

The function is:
void Alive::FromRoom ()
{
list<Alive>::iterator iter = room->living.begin();
while (iter != room->living.end())
{
if (*iter == *this)
{
room->living.erase(iter);
break;

else ++iter;
}

}

The error message is:
alive.cpp:29: no match for `Alive& == Alive&' operator

which is this line:
if (*iter == *this)

I've declared 'living' here:

class Room : public Baseobj
{
list<Alive> living;
};

So, I'm not sure how I should be doing this. If the error message can
be trusted, I need to define '==' as it applies to the 'Alive' class?
But, I don't understand what that would mean. I mean, I have the object
I want to remove from the list. It's 'this'. So, I don't understand
what more would be needed. The 'this' pointer points to an instance of
an object, doesn' it?
 
S

Sunil Varma

Jonathan said:
Hi. I'm having trouble figuring out what I should be doing here.

I'm trying to remove an object from a list.

The function is:
void Alive::FromRoom ()
{
list<Alive>::iterator iter = room->living.begin();
while (iter != room->living.end())
{
if (*iter == *this)
{
room->living.erase(iter);
break;

else ++iter;
}

}

The error message is:
alive.cpp:29: no match for `Alive& == Alive&' operator

which is this line:
if (*iter == *this)

I've declared 'living' here:

class Room : public Baseobj
{
list<Alive> living;
};

So, I'm not sure how I should be doing this. If the error message can
be trusted, I need to define '==' as it applies to the 'Alive' class?
But, I don't understand what that would mean. I mean, I have the object
I want to remove from the list. It's 'this'. So, I don't understand
what more would be needed. The 'this' pointer points to an instance of
an object, doesn' it?

You cannot two objects using "==" operator.
(*iter==*this)
Both iter and this when derefernced are objects.
You need to write a function overloading the "==" operator in Alive
class.
 
M

Mark P

Jonathan said:
Hi. I'm having trouble figuring out what I should be doing here.

I'm trying to remove an object from a list.

The function is:
void Alive::FromRoom ()
{
list<Alive>::iterator iter = room->living.begin();
while (iter != room->living.end())
{
if (*iter == *this)
{
room->living.erase(iter);
break;

missing '}' here
else ++iter;
}

}

The error message is:
alive.cpp:29: no match for `Alive& == Alive&' operator

which is this line:
if (*iter == *this)

The error says exactly what the problem is. *iter and *this are both of
type Alive (technically, Alive& but that's not essential here) and
you're applying operator== to them without having defined such an operator.

You can define a member function of Alive:
bool Alive::eek:perator== (const Alive& rhs) const {...}
or a nonmember function:
bool operator== (const Alive& lhs, const Alive& rhs) {...}

Alternatively, depending upon your implementation, you might want to
instead compare as:

if (&*iter == this) ...

which is a pointer comparison. This will only work if the object *this
is the same object (i.e., stored in the same location in memory) as the
object in the list. Whether this is the case will depend upon your
specific implementation.

Mark
 
D

Dietmar Kuehl

Jonathan said:
I'm trying to remove an object from a list.

However, you problem is [obviously] not related at all to removing
an object from the list. It is related to identifying the object
you want to remove.
If the error message can
be trusted, I need to define '==' as it applies to the 'Alive' class?

I would consider this to be accurate and in general most error
messages can be trusted. At least, it is a good bet to start by
trusting it. Once you have eliminated the possibility that the
error message is true, you might want to seek other reasons.
But, I don't understand what that would mean.

Well, it means that there is no 'operator==()' taking two 'Alive'
objects as arguments. I think, this is pretty straight forward...
I mean, I have the object I want to remove from the list. It's
'this'.

Note, that removing 'this' from the list will also destroy the
object whose method is currently running. This is not by itself
a problem but it is worth noting that removal of 'this' will
render all further accesses to the object invalid.
So, I don't understand what more would be needed.

Your use of 'operator==()' compares the two objects by their values,
not by their identity. To do so, you need to define an 'operator==()'
which takes two 'Alive' objects or reference to such objects as
arguments.
The 'this' pointer points to an instance of
an object, doesn' it?

If you want to compare the object's identities, you would use
something like this:

if (&*iter == this)
...

The subexpression '&*iter' obtains a reference to the object referred
to be 'iter' and then takes this object's address. This address can
readily be compared to 'this'.
 
J

Jonathan

Thank you all very much.
if (&*iter == this)
is exactly what I needed to know, and all the comments were very
helpful.

But, this brings up a follow-up question. (By the way, would it be more
appropriate to post it by starting a new topic?)
Note, that removing 'this' from the list will also destroy the
object whose method is currently running. This is not by itself
a problem but it is worth noting that removal of 'this' will
render all further accesses to the object invalid.

Again, I seem to be misunderstanding how things work. Using a textbook
type of analogy, let's say I have a STL list of objects that are on
the Table. The Table list includes a Plate, Candlestick, Cup, and a
Cat. Now, I want to remove the 'Cat', from the Table, but I don't have
the slightest desire to destroy the 'Cat'. What's the proper way to
proceed? Make sure that I copy the 'Cat' somewhere else first? Forget
about using the STL, and just make a linked list, C-style?
 
B

Ben Pope

Jonathan said:
Again, I seem to be misunderstanding how things work. Using a textbook
type of analogy, let's say I have a STL list of objects that are on
the Table. The Table list includes a Plate, Candlestick, Cup, and a
Cat. Now, I want to remove the 'Cat', from the Table, but I don't have
the slightest desire to destroy the 'Cat'. What's the proper way to
proceed? Make sure that I copy the 'Cat' somewhere else first? Forget
about using the STL, and just make a linked list, C-style?

Presumably you have a list like so:
std::list<TableItem*> tableItems;

The list does not manage the lifetime of those objects, only of the
pointers to those objects. Removing the pointer does not destroy the
TableItem.

If you have this instead:
std::list<TableItem> tableItems;

Then I'm not sure how they could be of different type (Cat, Plate,
etc.), forgetting that I shall continue:

STL containers rely upon copy-semantics, if it's not in the list, it
doesn't exist. Putting it into the list creates a copy of the Item,
removing from the list removes the copy. In this case, you do not
destroy the (original) cat.

If you want to remove the cat, and keep a copy then that's a different
problem, I suggest you find the cat, copy it and then remove it, as you say.

Ben Pope
 

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

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top