Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. ATL / WTL / STL
  4. sorting an STL list of =references= to objects

sorting an STL list of =references= to objects

Scheduled Pinned Locked Moved ATL / WTL / STL
c++algorithmscssgraphics
9 Posts 2 Posters 1 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    kerchunk
    wrote on last edited by
    #1

    VC++6 on XP Pro greetings all, I've created an STL list object that stores =references= to objects. I've overloaded the less-than operator like numerous examples on the 'net say to do. The following code compiles and executes but does not sort - actually the order does change but not in a sorted order. I'm stumped - there must be some nuance I'm missing.

    // sort_example.cpp : Defines the entry point for the console application.
    //

    #include "stdafx.h"
    #include <iostream>
    #include <iomanip>
    #include <fstream>
    #include <string>
    #include <list>
    #include <iterator>
    #include <vector>
    #include <algorithm>

    using namespace std;

    struct pstchip_pin_wor {
    string primitive;
    string pin_name;
    string pin_number;

    /\* optional constructors \*/
    pstchip\_pin\_wor( string aa, string bb, string cc) {
        primitive  = aa;
        pin\_name   = bb;
        pin\_number = cc;
    }
    
    //overridding operators
    pstchip\_pin\_wor& pstchip\_pin\_wor::operator = (const pstchip\_pin\_wor &itemToCopy) {
        this->primitive  = itemToCopy.primitive;
        this->pin\_name   = itemToCopy.pin\_name;
        this->pin\_number = itemToCopy.pin\_number;
        return \*this;
    }
    
    int pstchip\_pin\_wor::operator == ( const pstchip\_pin\_wor& itemToCompare) const {
        if( this->primitive == itemToCompare.primitive  && this->pin\_name  < itemToCompare.pin\_name ) return 1;
        return 0;
    }
    
    int pstchip\_pin\_wor::operator  < ( const pstchip\_pin\_wor& itemToCompare) const {
        if( this->primitive  < itemToCompare.primitive ) return 1;
        if( this->primitive == itemToCompare.primitive && this->pin\_name < itemToCompare.pin\_name) return 1;
        return 0;
    }
    

    };

    //main function
    int main(int argc, char* argv[]) {

    int nRetCode = 0;

    list<pstchip_pin_wor*> wors_pstchip_pins;

    //populate list
    wors_pstchip_pins.push_back( new pstchip_pin_wor( "Europe", "Spain", "Madrid" ) );
    wors_pstchip_pins.push_back( new pstchip_pin_wor( "North America", "USA", "Washington DC" ) );
    wors_pstchip_pins.push_back( new pstchip_pin_wor( "North America", "Canada", "Ottawa" ) );
    wors_pstchip_pins.push_back( new pstchip_pin_wor( "Europe", "Germany", "Berlin" ) );
    wors_pstchip_pins.push_back( new pstchip_pin_wor( "South America", "Brazil", "Sao Paulo" ) );
    wors_pstchip_pins.push_back( new pstchip_pin_wor( "North America",

    K 1 Reply Last reply
    0
    • K kerchunk

      VC++6 on XP Pro greetings all, I've created an STL list object that stores =references= to objects. I've overloaded the less-than operator like numerous examples on the 'net say to do. The following code compiles and executes but does not sort - actually the order does change but not in a sorted order. I'm stumped - there must be some nuance I'm missing.

      // sort_example.cpp : Defines the entry point for the console application.
      //

      #include "stdafx.h"
      #include <iostream>
      #include <iomanip>
      #include <fstream>
      #include <string>
      #include <list>
      #include <iterator>
      #include <vector>
      #include <algorithm>

      using namespace std;

      struct pstchip_pin_wor {
      string primitive;
      string pin_name;
      string pin_number;

      /\* optional constructors \*/
      pstchip\_pin\_wor( string aa, string bb, string cc) {
          primitive  = aa;
          pin\_name   = bb;
          pin\_number = cc;
      }
      
      //overridding operators
      pstchip\_pin\_wor& pstchip\_pin\_wor::operator = (const pstchip\_pin\_wor &itemToCopy) {
          this->primitive  = itemToCopy.primitive;
          this->pin\_name   = itemToCopy.pin\_name;
          this->pin\_number = itemToCopy.pin\_number;
          return \*this;
      }
      
      int pstchip\_pin\_wor::operator == ( const pstchip\_pin\_wor& itemToCompare) const {
          if( this->primitive == itemToCompare.primitive  && this->pin\_name  < itemToCompare.pin\_name ) return 1;
          return 0;
      }
      
      int pstchip\_pin\_wor::operator  < ( const pstchip\_pin\_wor& itemToCompare) const {
          if( this->primitive  < itemToCompare.primitive ) return 1;
          if( this->primitive == itemToCompare.primitive && this->pin\_name < itemToCompare.pin\_name) return 1;
          return 0;
      }
      

      };

      //main function
      int main(int argc, char* argv[]) {

      int nRetCode = 0;

      list<pstchip_pin_wor*> wors_pstchip_pins;

      //populate list
      wors_pstchip_pins.push_back( new pstchip_pin_wor( "Europe", "Spain", "Madrid" ) );
      wors_pstchip_pins.push_back( new pstchip_pin_wor( "North America", "USA", "Washington DC" ) );
      wors_pstchip_pins.push_back( new pstchip_pin_wor( "North America", "Canada", "Ottawa" ) );
      wors_pstchip_pins.push_back( new pstchip_pin_wor( "Europe", "Germany", "Berlin" ) );
      wors_pstchip_pins.push_back( new pstchip_pin_wor( "South America", "Brazil", "Sao Paulo" ) );
      wors_pstchip_pins.push_back( new pstchip_pin_wor( "North America",

      K Offline
      K Offline
      kerchunk
      wrote on last edited by
      #2

      I've improved my testcase to use two lists, one a list of structs and the original list of pointers-to-structs and added some code to populate, list, sort, and list again both lists. The list-of-structs sorts correctly while the list-of-pointers-to-structs does not. So it's got to be something with the how the overloaded operators are set up. Any ideas on how to adjust them to work right? [code] // sort_example.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> #include <iomanip> #include <fstream> #include <string> #include <list> #include <iterator> #include <vector> #include <algorithm> using namespace std; struct pstchip_pin_wor { string primitive; string pin_name; string pin_number; /* optional constructors */ pstchip_pin_wor( string aa, string bb, string cc) { primitive = aa; pin_name = bb; pin_number = cc; } //overridding operators pstchip_pin_wor& pstchip_pin_wor::operator = (const pstchip_pin_wor &itemToCopy) { this->primitive = itemToCopy.primitive; this->pin_name = itemToCopy.pin_name; this->pin_number = itemToCopy.pin_number; return *this; } int pstchip_pin_wor::operator == ( const pstchip_pin_wor& itemToCompare) { if( this->primitive == itemToCompare.primitive && this->pin_name < itemToCompare.pin_name ) return 1; return 0; } int pstchip_pin_wor::operator < ( const pstchip_pin_wor& itemToCompare) { if( this->primitive < itemToCompare.primitive ) return 1; if( this->primitive == itemToCompare.primitive && this->pin_name < itemToCompare.pin_name) return 1; return 0; } }; //main function int main(int argc, char* argv[]) { int nRetCode = 0; list<pstchip_pin_wor> rows_pstchip_pins; list<pstchip_pin_wor*> wors_pstchip_pins; //populate list rows_pstchip_pins.push_back( pstchip_pin_wor( "Europe", "Spain", "Madrid" ) ); rows_pstchip_pins.push_back( pstchip_pin_wor( "North America", "USA", "Washington DC" ) ); rows_pstchip_pins.push_back( pstchip_pin_wor( "North America", "Canada", "Ottawa" ) ); rows_pstchip_pins.push_back( pstchip_pin_wor( "Europe", "Germany", "Berlin" ) ); rows_pstchip_pins.push_back( pstchip_pin_wor( "South America", "Brazil", "Sao Paulo" )

      S 1 Reply Last reply
      0
      • K kerchunk

        I've improved my testcase to use two lists, one a list of structs and the original list of pointers-to-structs and added some code to populate, list, sort, and list again both lists. The list-of-structs sorts correctly while the list-of-pointers-to-structs does not. So it's got to be something with the how the overloaded operators are set up. Any ideas on how to adjust them to work right? [code] // sort_example.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> #include <iomanip> #include <fstream> #include <string> #include <list> #include <iterator> #include <vector> #include <algorithm> using namespace std; struct pstchip_pin_wor { string primitive; string pin_name; string pin_number; /* optional constructors */ pstchip_pin_wor( string aa, string bb, string cc) { primitive = aa; pin_name = bb; pin_number = cc; } //overridding operators pstchip_pin_wor& pstchip_pin_wor::operator = (const pstchip_pin_wor &itemToCopy) { this->primitive = itemToCopy.primitive; this->pin_name = itemToCopy.pin_name; this->pin_number = itemToCopy.pin_number; return *this; } int pstchip_pin_wor::operator == ( const pstchip_pin_wor& itemToCompare) { if( this->primitive == itemToCompare.primitive && this->pin_name < itemToCompare.pin_name ) return 1; return 0; } int pstchip_pin_wor::operator < ( const pstchip_pin_wor& itemToCompare) { if( this->primitive < itemToCompare.primitive ) return 1; if( this->primitive == itemToCompare.primitive && this->pin_name < itemToCompare.pin_name) return 1; return 0; } }; //main function int main(int argc, char* argv[]) { int nRetCode = 0; list<pstchip_pin_wor> rows_pstchip_pins; list<pstchip_pin_wor*> wors_pstchip_pins; //populate list rows_pstchip_pins.push_back( pstchip_pin_wor( "Europe", "Spain", "Madrid" ) ); rows_pstchip_pins.push_back( pstchip_pin_wor( "North America", "USA", "Washington DC" ) ); rows_pstchip_pins.push_back( pstchip_pin_wor( "North America", "Canada", "Ottawa" ) ); rows_pstchip_pins.push_back( pstchip_pin_wor( "Europe", "Germany", "Berlin" ) ); rows_pstchip_pins.push_back( pstchip_pin_wor( "South America", "Brazil", "Sao Paulo" )

        S Offline
        S Offline
        Simple Inheritance
        wrote on last edited by
        #3

        If you really need to maintain a list of pointers, you can add one user-defined function (as global or as static member to the class) that compares two objects with pointers to them as parameters.

        static bool less_than(pstchip_pin_wor* elem1, pstchip_pin_wor* elem2)
        {
        return *elem1 < *elem2;
        }

        Then you use the sort with the user-defined function as parameter.

        wors_pstchip_pins.sort(pstchip_pin_wor::less_than);

        K 1 Reply Last reply
        0
        • S Simple Inheritance

          If you really need to maintain a list of pointers, you can add one user-defined function (as global or as static member to the class) that compares two objects with pointers to them as parameters.

          static bool less_than(pstchip_pin_wor* elem1, pstchip_pin_wor* elem2)
          {
          return *elem1 < *elem2;
          }

          Then you use the sort with the user-defined function as parameter.

          wors_pstchip_pins.sort(pstchip_pin_wor::less_than);

          K Offline
          K Offline
          kerchunk
          wrote on last edited by
          #4

          Thank You for your reply! It's GMT -07:00 here so I'll give your suggestion a try on the morrow. Thanks again, kerchunk

          K 1 Reply Last reply
          0
          • K kerchunk

            Thank You for your reply! It's GMT -07:00 here so I'll give your suggestion a try on the morrow. Thanks again, kerchunk

            K Offline
            K Offline
            kerchunk
            wrote on last edited by
            #5

            I made the changes you suggested but now the code does not compile. Your instructions were clear - did I fat-finger something? [code] // sort_example.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> #include <iomanip> #include <fstream> #include <string> #include <list> #include <iterator> #include <vector> #include <algorithm> using namespace std; struct pstchip_pin_row { string primitive; string pin_name; string pin_number; /* optional constructors */ pstchip_pin_row( string aa, string bb, string cc) { primitive = aa; pin_name = bb; pin_number = cc; } //overridding operators pstchip_pin_row& operator = (const pstchip_pin_row &itemToCopy) { this->primitive = itemToCopy.primitive; this->pin_name = itemToCopy.pin_name; this->pin_number = itemToCopy.pin_number; return *this; } bool operator == ( const pstchip_pin_row& itemToCompare) { if( this->primitive == itemToCompare.primitive && this->pin_name < itemToCompare.pin_name ) return true; return false; } bool operator < ( const pstchip_pin_row& itemToCompare) { if( this->primitive < itemToCompare.primitive ) return true; if( this->primitive == itemToCompare.primitive && this->pin_name < itemToCompare.pin_name) return true; return false; } }; struct pstchip_pin_wor { string primitive; string pin_name; string pin_number; /* optional constructors */ pstchip_pin_wor( string aa, string bb, string cc) { primitive = aa; pin_name = bb; pin_number = cc; } //overridding operators pstchip_pin_wor& operator = (const pstchip_pin_wor &itemToCopy) { this->primitive = itemToCopy.primitive; this->pin_name = itemToCopy.pin_name; this->pin_number = itemToCopy.pin_number; return *this; } bool operator == ( const pstchip_pin_wor& itemToCompare) { if( this->primitive == itemToCompare.primitive && this->pin_name < itemToCompare.pin_name ) return true; return false; } bool operator < ( const pstchip_pin_wor& itemToCompare) { if( this->primitive < itemToCompare.primitive) return true; if(

            S 1 Reply Last reply
            0
            • K kerchunk

              I made the changes you suggested but now the code does not compile. Your instructions were clear - did I fat-finger something? [code] // sort_example.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> #include <iomanip> #include <fstream> #include <string> #include <list> #include <iterator> #include <vector> #include <algorithm> using namespace std; struct pstchip_pin_row { string primitive; string pin_name; string pin_number; /* optional constructors */ pstchip_pin_row( string aa, string bb, string cc) { primitive = aa; pin_name = bb; pin_number = cc; } //overridding operators pstchip_pin_row& operator = (const pstchip_pin_row &itemToCopy) { this->primitive = itemToCopy.primitive; this->pin_name = itemToCopy.pin_name; this->pin_number = itemToCopy.pin_number; return *this; } bool operator == ( const pstchip_pin_row& itemToCompare) { if( this->primitive == itemToCompare.primitive && this->pin_name < itemToCompare.pin_name ) return true; return false; } bool operator < ( const pstchip_pin_row& itemToCompare) { if( this->primitive < itemToCompare.primitive ) return true; if( this->primitive == itemToCompare.primitive && this->pin_name < itemToCompare.pin_name) return true; return false; } }; struct pstchip_pin_wor { string primitive; string pin_name; string pin_number; /* optional constructors */ pstchip_pin_wor( string aa, string bb, string cc) { primitive = aa; pin_name = bb; pin_number = cc; } //overridding operators pstchip_pin_wor& operator = (const pstchip_pin_wor &itemToCopy) { this->primitive = itemToCopy.primitive; this->pin_name = itemToCopy.pin_name; this->pin_number = itemToCopy.pin_number; return *this; } bool operator == ( const pstchip_pin_wor& itemToCompare) { if( this->primitive == itemToCompare.primitive && this->pin_name < itemToCompare.pin_name ) return true; return false; } bool operator < ( const pstchip_pin_wor& itemToCompare) { if( this->primitive < itemToCompare.primitive) return true; if(

              S Offline
              S Offline
              Simple Inheritance
              wrote on last edited by
              #6

              You fattened the parameters of compareFunc with const specifiers. It works when you remove them. If you want to define compareFunc with const parameters:

              static bool compareFunc( const pstchip_pin_wor* a, const pstchip_pin_wor* b)

              then you have to define the operator < as a const member:

              bool operator < ( const pstchip_pin_wor& itemToCompare) const

              modified on Wednesday, December 2, 2009 5:13 PM

              K 1 Reply Last reply
              0
              • S Simple Inheritance

                You fattened the parameters of compareFunc with const specifiers. It works when you remove them. If you want to define compareFunc with const parameters:

                static bool compareFunc( const pstchip_pin_wor* a, const pstchip_pin_wor* b)

                then you have to define the operator < as a const member:

                bool operator < ( const pstchip_pin_wor& itemToCompare) const

                modified on Wednesday, December 2, 2009 5:13 PM

                K Offline
                K Offline
                kerchunk
                wrote on last edited by
                #7

                OK I unfattened compareFunc by removing the two 'const's. Under VC++6 the program now throws one compiler error: --------- C:\mystuff\sort_example.cpp(127) : error C2664: 'void __thiscall std::list<struct pstchip_pin_wor *,class std::allocator<struct pstchip_pin_wor *> >::sort(struct std::greater<struct pstchip_pin_wor *> )' : cannot convert parameter 1 from 'bool (__cdecl *)(struct pstchip_pin_wor *,struct pstchip_pin_wor *)' to 'struct std::greater<struct pstchip_pin_wor *>' No constructor could take the source type, or constructor overload resolution was ambiguous Error executing cl.exe. ---------- ??? Do I need to overload the std::greater function? And if so how? Thank You, kerchunk

                S 1 Reply Last reply
                0
                • K kerchunk

                  OK I unfattened compareFunc by removing the two 'const's. Under VC++6 the program now throws one compiler error: --------- C:\mystuff\sort_example.cpp(127) : error C2664: 'void __thiscall std::list<struct pstchip_pin_wor *,class std::allocator<struct pstchip_pin_wor *> >::sort(struct std::greater<struct pstchip_pin_wor *> )' : cannot convert parameter 1 from 'bool (__cdecl *)(struct pstchip_pin_wor *,struct pstchip_pin_wor *)' to 'struct std::greater<struct pstchip_pin_wor *>' No constructor could take the source type, or constructor overload resolution was ambiguous Error executing cl.exe. ---------- ??? Do I need to overload the std::greater function? And if so how? Thank You, kerchunk

                  S Offline
                  S Offline
                  Simple Inheritance
                  wrote on last edited by
                  #8

                  BUG: The STL list::sort() Function Doesn't Sort a List of Pointers http://support.microsoft.com/default.aspx?scid=kb;EN-US;q265109 The Standard Template Library (STL) list::sort function doesn't sort a list of pointers when a predicate function is defined for sorting. VC6 is a ten-year old compiler now. The bug is not present in VC2008 or MinGW. Your code is implemented below with the workaround described in KB265109. ________________________________________________________________________________________ #include <iostream> #include <string> #include <list> using namespace std; struct pstchip_pin_wor {       string primitive;       string pin_name;       string pin_number;       pstchip_pin_wor( string aa, string bb, string cc)       {             primitive   = aa;             pin_name   = bb;           pin_number = cc;      }       pstchip_pin_wor& pstchip_pin_wor::operator= (const pstchip_pin_wor &itemToCopy)       {             if(&itemToCopy != this)           {                this->primitive   = itemToCopy.primitive;                this->pin_name   = itemToCopy.pin_name;                this->pin_number = itemToCopy.pin_number;           }           return *this;      }      int pstchip_pin_wor::operator == ( const pstchip_pin_wor& itemToCompare) const      {           if( this->primitive == itemToCompare.primitive   && this->pin_name   < itemToCompare.pin_name )                return 1;           return 0;      }      int pstchip_pin_wor::operator   < ( const pstchip_pin_wor&

                  K 1 Reply Last reply
                  0
                  • S Simple Inheritance

                    BUG: The STL list::sort() Function Doesn't Sort a List of Pointers http://support.microsoft.com/default.aspx?scid=kb;EN-US;q265109 The Standard Template Library (STL) list::sort function doesn't sort a list of pointers when a predicate function is defined for sorting. VC6 is a ten-year old compiler now. The bug is not present in VC2008 or MinGW. Your code is implemented below with the workaround described in KB265109. ________________________________________________________________________________________ #include <iostream> #include <string> #include <list> using namespace std; struct pstchip_pin_wor {       string primitive;       string pin_name;       string pin_number;       pstchip_pin_wor( string aa, string bb, string cc)       {             primitive   = aa;             pin_name   = bb;           pin_number = cc;      }       pstchip_pin_wor& pstchip_pin_wor::operator= (const pstchip_pin_wor &itemToCopy)       {             if(&itemToCopy != this)           {                this->primitive   = itemToCopy.primitive;                this->pin_name   = itemToCopy.pin_name;                this->pin_number = itemToCopy.pin_number;           }           return *this;      }      int pstchip_pin_wor::operator == ( const pstchip_pin_wor& itemToCompare) const      {           if( this->primitive == itemToCompare.primitive   && this->pin_name   < itemToCompare.pin_name )                return 1;           return 0;      }      int pstchip_pin_wor::operator   < ( const pstchip_pin_wor&

                    K Offline
                    K Offline
                    kerchunk
                    wrote on last edited by
                    #9

                    WOOHOO!! It works great! Good catch, I'd've never thought to check the compiler itself, and lo sure enough there's a KB against exactly this issue. Thank You So Much for seeing me through this! CASE CLOSED kerchunk

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups