Thread: STL list.sort() question

  1. #1
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391

    STL list.sort() question

    if you have a hypothetical class like:
    Code:
    class myClass{
    
        public:
    
        private:
    
            int n;
            string m_string;
            char m_char;
            // etc.
    };
    is there a way to use the STL list.sort() function to sort with respect to one of your private members? in this case i'd like to sort with respect to the integer "n".
    ?????????

  2. #2
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Yes... you'd have to create an appropriate comparison function object and pass that to the sort function or overload the less-than operator for the class.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  3. #3
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391
    oh great, it can be done.

    how might the overloaded operator look?

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    how might the overloaded operator look?
    It would be a free function with the prototype:
    Code:
    bool operator<(const myClass& lhs, const myClass& rhs);
    If you do not provide an accessor for n, then it should be a friend function of myClass.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Here's one way (using a non-member, non-friend function):
    Code:
    bool operator<( const myClass& lhs, const myClass& rhs )
    {
        return (lhs.GetN() < rhs.GetN());
    }
    This assumes that you have a public member function in myClass that returns the value of n.

  6. #6
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391
    thank you all!

    you guys are very helpful.

  7. #7
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391
    hmmmm.

    my compiler is telling me that the operator< must take exactly on argument.
    here's the errors I'm getting:
    Code:
    operator1.cpp:15: error: ‘bool testObj::operator<(const testObj&, const testObj&)’ must take exactly one argument
    operator1.cpp: In member function ‘bool testObj::operator<(const testObj&, const testObj&)’:
    operator1.cpp:17: error: no matching function for call to ‘testObj::get_n() const’
    operator1.cpp:13: note: candidates are: int testObj::get_n() <near match>
    operator1.cpp:17: error: no matching function for call to ‘testObj::get_n() const’
    operator1.cpp:13: note: candidates are: int testObj::get_n() <near match>
    make: *** [operator1.o] Error 1

  8. #8
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391
    here's the class that I'm compiling:
    Code:
    class testObj{
    	
    	public:
    	
    		testObj(int x) : n(x) {};
    	
    		void set_n(int x){ n = x; };
    		int get_n(){ return n; };
    		
    		bool operator<(const testObj& lhs, const testObj& rhs){
    			
    			return (lhs.get_n() < rhs.get_n());
    		}
    		
    	private:
    	
    		int n;
    };

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You EITHER have one object as input to operator< and declare it as a class member function, or you declare it OUTSIDE of the class, with two parameters.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391
    okay. i think i got sort to work like i wanted to, but i have no way of seeing the effect.

    i'd like to have a fucntion like:
    Code:
    void show_list(list<testObj>& mlist){
    
        for(list<testObj>::iterator i = mlist.begin(); i != mlist.end(); i++){
    
            cout << *i << endl;
        }
    }
    that would behave the same way if i had a simple list of integers.

    I'm guessing i would need to overload the operator*() but i'm not sure how.

    If i created my own template, my iterator class would have its own pointer so that it could be overloaded like:
    Code:
    const T& operator*() const { return curr->data; };
    
    T& operator*() { return curr->data; };
    but of course i'm using the STL so that won't work. any ideas?

  11. #11
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    You would actually need to overload the operator<< for your class. The operator* is already overloaded for the iterator to return a reference to the object in the list, so that's why you don't have to worry about that.

    The operator<< is a non-member function with this signature:
    Code:
    std::ostream& operator<<(std::ostream& out, const testObj& obj);
    Again, it may need to be a friend if it accesses internal data in the class.

    Unlike the operator< there is no member function version that will work, it has to be a non-member (free) function.

  12. #12
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    You want it to be like this:
    Code:
    		friend bool operator<(const testObj& lhs, const testObj& rhs){
    			
    			return (lhs.n < rhs.n);
    		}
    };
    show_list can be written like this to show that it is sorted:
    Code:
    void show_list(const list<testObj>& mlist){
    
        for(list<testObj>::const_iterator i = mlist.begin(); i != mlist.end(); ++i){
            cout << i->get_n() << endl;
        }
    }
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  13. #13
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Following the trend, it should be really easy to devise a STL solution if you're going to be writing stream inserters anyway. For example:
    Code:
    #include <algorithm>
    #include <iostream>
    #include <ostream>
    
    template<class someType> struct display 
    {
        void operator() (const someType & that) const
        {
            std::cout<<that<<std::endl;
        }
    };
    
    int main()
    {
        typedef /**myType**/ yourType;
        typedef std::list<yourType> yourContainer;
    
        yourType it;
        yourContainer foo;
    
        for( int items = 0; items < 10; ++items ) {
            std::cin>>it;
            foo.push_back( it );
        }
        std::for_each( foo.begin(), foo.end(), display<yourType>() );
    }

  14. #14
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    But you can do that without the helper if your operator<< is defined:
    Code:
    std::copy(foo.begin(), foo.end(), std::ostream_iterator<yourType>(std::cout, "\n"));

  15. #15
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391
    cool. everythings working beautifully now.

    i learned a lot in this discussion!

    thank you all!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Design layer question
    By mdoland in forum C# Programming
    Replies: 0
    Last Post: 10-19-2007, 04:22 AM
  2. STL preformance question
    By l2u in forum C++ Programming
    Replies: 9
    Last Post: 12-07-2006, 05:36 PM
  3. STL algorithm question
    By Reggie in forum C++ Programming
    Replies: 1
    Last Post: 04-22-2003, 09:04 AM
  4. opengl DC question
    By SAMSAM in forum Game Programming
    Replies: 6
    Last Post: 02-26-2003, 09:22 PM
  5. question about STL
    By free2run in forum C++ Programming
    Replies: 2
    Last Post: 12-16-2002, 12:12 PM