Sorting 'std::list' -s filled with class-pointers leads to a compile error
-
Hi! I've been using MSVC++ 6.0 for about 5 years now, and by now, I haven't got any serious problems. But today, I'd have liked to create a simple std::list with class-pointers in it. By that point everything were fine. But when I wanted to sort the list by a custom sorter, everything went wrong. I could not mangeged to sort the list, I always got the same compile error: d:\projects\dc\try\try.cpp(42) : error C2664: 'void __thiscall std::list<class CTest *,class std::allocatorclass CTest *> >::sort(struct std::greater<class CTest *>)' : cannot convert parameter 1 from 'class CTestSorter' to 'struct std::greater<cla ss CTest *>' No constructor could take the source type, or constructor overload resolution was ambiguous Please tell me, how could I sort such kind of lists in Visual C++ 6.0. Thx in forward. The code I tried to compile is here:
#include #include <list> #include <math.h> using namespace std; class CTest { friend class CTestSorter; protected: int sortby; int other; public: CTest() : sortby(0), other(0) { }; CTest(int first, int second) : sortby(first), other(second) { }; void Write() { cout << sortby << ". - " << other << "\n"; } }; class CTestSorter { public: bool operator() ( CTest* first, CTest*second ) { return first->sortby < second->sortby; } }; int main(int argc, char* argv[]) { list<CTest*> mylist; int i; cout << "Hello!\n"; for( i=0;i<10;i++ ) { CTest* obj=new CTest( 10-i, rand() ); mylist.push_back( obj ); } mylist.sort( CTestSorter() ); for( list<CTest*>::iterator it=mylist.begin();it!=mylist.end();it++ ) { (*it)->Write(); } return 0; }
-
Hi! I've been using MSVC++ 6.0 for about 5 years now, and by now, I haven't got any serious problems. But today, I'd have liked to create a simple std::list with class-pointers in it. By that point everything were fine. But when I wanted to sort the list by a custom sorter, everything went wrong. I could not mangeged to sort the list, I always got the same compile error: d:\projects\dc\try\try.cpp(42) : error C2664: 'void __thiscall std::list<class CTest *,class std::allocatorclass CTest *> >::sort(struct std::greater<class CTest *>)' : cannot convert parameter 1 from 'class CTestSorter' to 'struct std::greater<cla ss CTest *>' No constructor could take the source type, or constructor overload resolution was ambiguous Please tell me, how could I sort such kind of lists in Visual C++ 6.0. Thx in forward. The code I tried to compile is here:
#include #include <list> #include <math.h> using namespace std; class CTest { friend class CTestSorter; protected: int sortby; int other; public: CTest() : sortby(0), other(0) { }; CTest(int first, int second) : sortby(first), other(second) { }; void Write() { cout << sortby << ". - " << other << "\n"; } }; class CTestSorter { public: bool operator() ( CTest* first, CTest*second ) { return first->sortby < second->sortby; } }; int main(int argc, char* argv[]) { list<CTest*> mylist; int i; cout << "Hello!\n"; for( i=0;i<10;i++ ) { CTest* obj=new CTest( 10-i, rand() ); mylist.push_back( obj ); } mylist.sort( CTestSorter() ); for( list<CTest*>::iterator it=mylist.begin();it!=mylist.end();it++ ) { (*it)->Write(); } return 0; }
You're doing it fine... the problem lies in Dinkumware STL's implementation. The version you have was written many years ago for VC 5.0, which lacks proper support for template members, like templatized
list::sort
. Not that MSVC 6.0 is much stronger wrt to templates, but at least it can manage this one. You just have to slightly modify the list::sort declaration in<list>
as described here[^]. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo -
You're doing it fine... the problem lies in Dinkumware STL's implementation. The version you have was written many years ago for VC 5.0, which lacks proper support for template members, like templatized
list::sort
. Not that MSVC 6.0 is much stronger wrt to templates, but at least it can manage this one. You just have to slightly modify the list::sort declaration in<list>
as described here[^]. Joaquín M López Muñoz Telefónica, Investigación y Desarrollo -
Actually, the page you linked containened a unworkin solution, but I browsed that thread, and found a really working one. I was very close to the correct solution, so to derive the std::greater<...> from the compare func, just I did it reverse. Anyway really a 'big' thanks you for the help. :-D
-
Actually, the page you linked containened a unworkin solution, but I browsed that thread, and found a really working one. I was very close to the correct solution, so to derive the std::greater<...> from the compare func, just I did it reverse. Anyway really a 'big' thanks you for the help. :-D
-
Hi, I have the same problem in a project. As I am a beginner, Could you write your solution; please ? thank you for you help.
Yes, of course. The solution is quite simple, almost trivial, but only if you think "with a microsofter's head". So the secret is that you, instead of deriving your sorter class from the std::greater<...>, have to derive the std::greater from your CYourSorterClass, which actually doesn't exists. to be clear: so just extend std with the following lines:
namespace std { template<> struct greater<CYourClass*> : public binary_function<CYourClass*, CYourClass*, bool> { bool operator()(const CYourClass*& x, const CYourClass*& y) const { // if you don't have the class' operator< overloaded return x->sortbyvalue < y->sortbyvalue; // if you do have return x < y; } }; }
then sort your list just the same way as it was a 'int' etc...:nodes.sort( std::greater<CYourClass*> ( ) );
that's it. I hope I could help. -
Yes, of course. The solution is quite simple, almost trivial, but only if you think "with a microsofter's head". So the secret is that you, instead of deriving your sorter class from the std::greater<...>, have to derive the std::greater from your CYourSorterClass, which actually doesn't exists. to be clear: so just extend std with the following lines:
namespace std { template<> struct greater<CYourClass*> : public binary_function<CYourClass*, CYourClass*, bool> { bool operator()(const CYourClass*& x, const CYourClass*& y) const { // if you don't have the class' operator< overloaded return x->sortbyvalue < y->sortbyvalue; // if you do have return x < y; } }; }
then sort your list just the same way as it was a 'int' etc...:nodes.sort( std::greater<CYourClass*> ( ) );
that's it. I hope I could help.