How to sort std::list<CMyClass*>?
-
Hello all... I'm a newbie struggling with the STL and have a question about how to sort std::list<CMyBaseClass*> objects. If I call list.sort(), CMyClass::operator<(const CMyClass &rhs) is never called, so I'm thinking that the pointers are causing problems. Is there a way I can sort this list of objects by defining a bool CMyClass::Compare function? Thanks for any information. -- ________________________ matt weagle matt_weagle@nospam.hotmail.com
-
Hello all... I'm a newbie struggling with the STL and have a question about how to sort std::list<CMyBaseClass*> objects. If I call list.sort(), CMyClass::operator<(const CMyClass &rhs) is never called, so I'm thinking that the pointers are causing problems. Is there a way I can sort this list of objects by defining a bool CMyClass::Compare function? Thanks for any information. -- ________________________ matt weagle matt_weagle@nospam.hotmail.com
Kind of. List has 2 sort functions, not just one. The first sorts the objects by value, meaning that in your example it's just sorting the pointers. The second takes a template function called greater, which can be used to create a custom sort function by defining your own. There is also std::sort, which will also work.
-
Hello all... I'm a newbie struggling with the STL and have a question about how to sort std::list<CMyBaseClass*> objects. If I call list.sort(), CMyClass::operator<(const CMyClass &rhs) is never called, so I'm thinking that the pointers are causing problems. Is there a way I can sort this list of objects by defining a bool CMyClass::Compare function? Thanks for any information. -- ________________________ matt weagle matt_weagle@nospam.hotmail.com
You can try this: std::list theList; bool Less(const CMyBaseClass* pFirst, const CMyBaseClass* pSecond) { return (*pFirst < *pSecond); } std::sort(theList.begin(), theList.end(), Less); Michael S. Scherotter Lead Software Architect Tartus Development, Inc.
-
You can try this: std::list theList; bool Less(const CMyBaseClass* pFirst, const CMyBaseClass* pSecond) { return (*pFirst < *pSecond); } std::sort(theList.begin(), theList.end(), Less); Michael S. Scherotter Lead Software Architect Tartus Development, Inc.
template<class Pred> void sort(greater<T> pr); So you want the predicate reversed, surely? std::list theList // function object, a bit more 'STL-style' class CMyBaseClassGreater { public: bool operator()(CMyBaseClass* pFirst, CMyBaseClass* pSecond) { return *pFirst > *pSecond; } } theList.sort(CMyBaseClassGreater()); std::sort won't work on a list, as it needs random access iterators, which list doesn't provide. You have to use std::list::sort().
-
template<class Pred> void sort(greater<T> pr); So you want the predicate reversed, surely? std::list theList // function object, a bit more 'STL-style' class CMyBaseClassGreater { public: bool operator()(CMyBaseClass* pFirst, CMyBaseClass* pSecond) { return *pFirst > *pSecond; } } theList.sort(CMyBaseClassGreater()); std::sort won't work on a list, as it needs random access iterators, which list doesn't provide. You have to use std::list::sort().
Thanks for the info. I actually got as far as figuring out the function object, but still couldn't get it to compile. I kept getting C2664 errors, complaining that it couldn't convert the function object to the proper type. Such as: error C2664: 'void __thiscall std::list<class CMyClass*,class std::allocator<class CMyClass*> >::sort(struct std::greater<class CMyClass *>)' : cannot convert parameter 1 from 'struct ObjectComp' in 'struct std:greater<class CMyClass*>' From digging through dejanews, I ran across a couple of threads that suggested that SP4 breaks template behavior of list::sort. Basically saying that the code snippet suggested works fine on gcc and Dinkumware's STL etc., but not on MSVC SP4. Is this possible? One day I will grow to like the STL :cool:
-
You can try this: std::list theList; bool Less(const CMyBaseClass* pFirst, const CMyBaseClass* pSecond) { return (*pFirst < *pSecond); } std::sort(theList.begin(), theList.end(), Less); Michael S. Scherotter Lead Software Architect Tartus Development, Inc.
-
Thanks for the suggestion but that is something that I had tried until I realized that you can't use the sort algorithm for a list container. The example you showed only works for random access containers. Thanks
You can sort using any predicate function. Here are some examples from code I am working with:
struct greater_magnitude { bool operator()(const CTFARect& x, const CTFARect& y) const { return (fabs(x.Value()) > fabs(y.Value())); } }; std::list m_lstRects; ... m_lstRects.sort(greater_magnitude());
In your case, you'd definestruct my_comparison_predicate
with memberbool my_comparison_predicate::operator()(const CTFARect *x, const CTFARect * y) const
after my example above. But to use this, you have to fix some bugs in the Microsoft standard C++ library. Look at Dunkumware's list of bug fixes for the VC++ standard library. Edit the standard library headers in "Program Files\Microsoft Visual Studio\vc98\include" to implement the fixes on the Dinkumware page. Then, you must edit the file "list" thus to allow the use of predicates:*** list Tue Jun 27 23:50:23 2000 --- list.original Mon Jun 15 05:00:00 1998 *************** *** 281,288 **** erase(_F++); else ++_F; } ! // typedef binder2nd<not_equal_to<_Ty> > _Pr1; // Fixed 2000 06 27 JMG ! template<class _Pr1> void remove_if(_Pr1 _Pr) // Fixed 2000 06 27 JMG {iterator _L = end(); for (iterator _F = begin(); _F != _L; ) if (_Pr(*_F)) --- 281,288 ---- erase(_F++); else ++_F; } ! typedef binder2nd<not_equal_to<_Ty> > _Pr1; ! void remove_if(_Pr1 _Pr) {iterator _L = end(); for (iterator _F = begin(); _F != _L; ) if (_Pr(*_F)) *************** *** 297,304 **** erase(_M); else _F = _M; } ! // typedef not_equal_to<_Ty> _Pr2; // Fixed 2000 06 27 JMG ! template<class _Pr2> void unique(_Pr2 _Pr) // Fixed 2000 06 27 JMG {iterator _F = begin(), _L = end(); if (_F != _L) for (iterator _M = _F; ++_M != _L; _M = _F) --- 297,304 ---- erase(_M); else _F = _M; } ! typedef not_equal_to<_Ty> _Pr2; ! void unique(_Pr2 _Pr) {iterator _F = begin(), _L = end(); if (_F != _L) for (iterator _M = _F; ++_M != _L; _M = _F) *************** *** 321,328 **** _Splice(_L1, _X, _F2, _L2); _Size += _X._Size; _X._Size = 0; }} ! // typedef greater<_Ty> _Pr3; // Fixed 2000 06 27 JMG ! template<class _Pr3> void merge(_Myt& _X, _Pr3 _Pr) // Fixed 2000 06 27 JMG {if (&_X