Click to See Complete Forum and Search --> : problems with std::list


Paul Caseley
March 26th, 2002, 08:45 AM
ok basically I'm trying to rewrite CPtrList so that I can recompile some code on UNIX (sounds nice doesn't it). I've written a class which uses std::list, but all the calls to this my class are the same as the calls to CPtrList (make sense?).

anyway, The problem is I've created a POSITION class so that I can traverse my list, this again holds a std::list<void*>::const_iterator, which is used to traverse the std::list in my CPtrList class.

Now on my PC in Visual Studio, I can intilise this as NULL, which helps a lot because when I overload the operator bool(), I can just test it for NULL.

my class looks a little like this:

class POSTION
{
public:
POSITION()
{
m_POSITION = NULL;
}

operator int()
{
if(m_POSITION == NULL)
return 1;
else
return 0;
}

//etc......


private:


std::list<void*>::iterator m_POSITION;

}




the reason I have done it this way is so that i can do:

POSITION pos;

pos = list.GetHeadPosition()

while(pos) //uses the operator int
{

}




now, as I said this all works fine on a PC, but on UNIX it will not allow me to set m_POSITION = NULL, and it won't allow me to do if(m_POSITION == NULL)...


I'm now stuck, I haven't got a clue what to do, basically with out using my class I need to be able to do the following on UNIX

std::list<void*>::const_iterator x;
x = NULL
if(x == NULL)
printf("stuff");


can anyone help, or understand what I've just posted?

Graham
March 26th, 2002, 11:39 AM
How much code relies on CPtrList? I only ask because, unless the amount is huge, you'd be better off biting the bullet and doing it "properly" - i.e. the STL way and not with Micro$soft's barmy, half-arsed containers.

Point 1 - std::list<>::iterator is not necessarily a pointer (in fact, it probably isn't), so assigning NULL (or, properly, 0) to it is not guaranteed to work. You might be able to get away with using list::end() instead of NULL, but that's going to need an object to get the end() from.

Point 2 - lists of void* are decidedly iffy. The point of std::list<> is to have a list of things that you want, not some ridiculous toy container like CPtrList, so storing void* in it is a bit like using an antique enamelled chinese box to store your old socks in.

No, you're embarking on a path of pain, frustration and premature baldness. My advice is to forget trying to emulate a bad container by using a good one, and to use the good container properly.

Sorry, that's probably not what you wanted to hear, but it's my honest advice.

He who breaks a thing to find out what it is, has left the path of wisdom - Gandalf

Paul McKenzie
March 26th, 2002, 01:19 PM
As Graham pointed out, is it worth all of this effort? Just use std::list<> and be done with it.

IMO, the CPtrList class was created so that MFC could coverup for its mistakes with CObList class. As a matter of fact, if you insisted on staying with MFC, you should have chosen the newer CList template class, and just make the template type a T*. If you're going to use MFC, CPtrList is the worst class you could have chosen. It is not typesafe, you need to cast all over the place to get the right value, etc. etc.

Having said this, reconsider what you are doing here. You used CPtrList to store pointers -- do you really need to store pointers? A major idea of C++ is typesafety. There is absolutely *no* need for you to be storing void pointers. From the looks of your code, it sounds like you are not familiar with writing template functions. If you were, you wouldn't have even wrote std::list<void*>, instead you would have written std::list<T*>, where T is a template argument.

If I were to write a replacement for CPtrList, it would look something like the following:

#include <list>
template <class T>
class CStdPtrList
{
public:
typedef std::list<T*>::iterator POSITION;
//...
private:
std::list<T*> m_List;

public:
POSITION GetHeadPosition() { return m_List.begin(); }
T* GetNext(POSITION& p)
{
if ( p == m_List.end() )
return NULL;
return *(++p);
}
}



I didn't compile the code above, but this is what I would have expected. Note how POSITION is an iterator type. As far as your NULL code -- get rid of it. There is no such thing as a NULL iterator.

Regards,

Paul McKenzie

Paul Caseley
March 27th, 2002, 03:10 AM
Yeah your both right, it is a pain in the bum. A Bit of Background, I've in inherited code which is over 260,000 lines, and there are around 2000 CptrLists, nice isn’t it. I need to port this code to unix so in my opinion writing a wrapper class is going to be the best idea.

I’ve sorted it now, basically you need to position to be a separate class, because you need to rewrite a load of the operators, so just use a typedef won’t work. Trust me this has taken 2 weeks so far and I’ve tried everything.

To fix it I’ve created a bool value as a member variable of my POSITION class, so where as before I was setting the iterator to NULL, now I’m setting the bool to false, it works, it’s not nice but it works….


Cheers for the advice anyway…