Re: Sorting a CList
On Thu, 14 Jun 2007 16:16:41 +0200, Anders Eriksson
<andis59@gmail.com> wrote:
I need to sort a CList (No, it not possible to use STL)
OK, but it would be interesting to compare MFC collection code + qsort
vs. STL code:
Your code (with qsort problem):
CList<CLaserObject*,CLaserObject*> m_listObjects;
CArray<CLaserObject*,CLaserObject*> vector;
POSITION pos = m_listObjects.GetHeadPosition();
int i=0;
while(pos != NULL)
{
vector.Add(m_listObjects.GetNext(pos));
}
// sort array
qsort(vector.GetData(),vector.GetSize(),sizeof(CLaserObject*),cmpLaserObject);
// empty list and fill it with the sorted data
m_listObjects.RemoveAll();
int n=vector.GetCount();
for(i=0;i<n;i++)
{
m_listObjects.AddTail(vector[i]);
}
int CSCMLaserDoc::cmpLaserObject(const void * v1, const void * v2)
{
CLaserObject *data1 = (CLaserObject *)v1;
CLaserObject *data2 = (CLaserObject *)v2;
}
A possible STL version:
std::list< CLaserObject * > laserObjects;
laserObjects.sort( LessByPointedValue<CLaserObject>() );
(just two simple lines of code! :)
and define an operator< on your laser object class:
bool operator<(
const CLaserObject & lhs,
const CLaserObject & rhs
);
Note that you have no need to pass from list to vector and back to
list, and to use the IMHO not very clear 'qsort' function (OK, qsort
was well designed in the C age, but with C++ more clear things could
be done...).
Note that you just need to call the list.sort() method.
The "strange" thing could be the LessByPointedValue<...> thing.
It is because the list stores *pointers* to CLaserObject, so you must
"teach" 'sort' method how to compare those pointed values.
The LessByPointedValue is a template you could reuse in other cases
when you have lists storing *pointers* to class instances (you could
put the LessByPointedValue template in your "programming tool-box" and
reuse it):
//
// operator < with pointed values
//
template <typename T>
class LessByPointedValue
: std::binary_function< const T *, const T *, bool >
{
public:
bool operator()( const T * x, const T * y ) const
{
return std::less<T>()( *x, *y );
}
};
I don't know if Boost has a "standard" version of this useful template
(maybe it has one, but I'm quite ignorant about Boost :(
If you need to use MFC collection, this CodeProject article might be
interesting:
http://www.codeproject.com/cpp/colsort.asp?df=100&forumid=2454&exp=0&select=223176
MrAsm