Advertisement

[STL] Getting iterator to element in list.

Started by March 10, 2001 09:02 AM
2 comments, last by gimp 23 years, 10 months ago
Seem to be having a slight problem
  
class CObject;
typedef std::list<CObject>::iterator ObjectPointer;

...

std::vector<CObject>	CObject::Objects;

...

const ObjectPointer CObject::New(void)
{
	Objects.resize(Objects.size() + 1);
	ObjectPointer NewObject = Objects.end()-1; <<<<<<<<<<<
	return NewObject;
}
  
No constructor could take the source type, or constructor overload resolution was ambiguous Can anyone see something wrong with that line that I can''t? Thanks Chris
Chris Brodie

  // Use a global list object or a store a list memeber in a classstd::list<CObject> m_vObjects;// Then create a temporary objectCObject ob;ob.member1 = 5;ob.member2 = 15;// And push back into your real listm_vObjects.push_back(ob);   


Zeblar Nagrim, Lord of Chaos
Advertisement
Your problem is that your "pointer" is a list iterator, and your collection is a vector. These are two diffent types completely. You can''t convert between two iterators of different types of containers.

The first thing you need to decide is what container you really want--list or vector? According to your function, which seems to allocate a new object from a global store of objects, you should probably use a list.

If what you''re trying to do in the class is return an iterator to the last object, you need to do this:
ObjectPointer NewObject = Objects.end ();
return --NewObject;

The reason is that your function tries to do a random access jump by subtracting 1. You can only do iterator+N (i.e. it-1) with random access iterators, and the only things that give you that are vectors and dequeues. A list gives you a bidirectional iterator, so you are allowed to do ++it and --it (but never it-1).

That''s how to make it compile, but it won''t work very well. Your container is one of CObject, not CObject*. If you are hoping to make CObject a base class and store derived objects, you won''t be able to do it. If you wanted a polymorphic container, you must use CObject*.

Since you''re returning a const iterator, you''ll only be able to use the const methods of the iterator, which means only dereferencing a const CObject (I believe, should probably check this), which means you won''t be able to call any non-const methods of CObject.

If your intention was only to not let the client iterate over the list, why not do this instead?
  CObject &CObject::New (){  // insert default object at end & return reference to it  return *Objects.insert (Objects.end ());}  


One-liner, good for inlining if you''ll be doing it a lot. Returns reference to the newly inserted object, not a copy of the object (which would be expensive).

Good luck.
Ack!

I''d say more than 50% of my code errors are from thoughless cut ''n paste''s.

Thanks for all the other info, I didn''t even consider the consequences of a const iterator.

Thanks again stoffel...


Zeblar : I tend to go with static databases with static New members as it hides the implementation from the clients. That way I can change the database shape (say vector\list) without touching client code. I''ve only just started using iterators yesterday, using the subscript elements until now has worked fine.

Thanks all,

Chris

This topic is closed to new replies.

Advertisement