std::list<string>::sort (Cmp) 
Author Message
 std::list<string>::sort (Cmp)

I'm trying to understand the mechanism to sort a list in several different
ways.  For instance, if I have a list of stings, I may want to sort the list
alphabetically, by length, by some known substring or by who knows what.
I've been reading Stroustrop (C++ Programming Language 3rd Edition) and
Deitel & Deitel (C++ How to Program) and both of these books indicate that
this should be an easy thing to do.  Well, I haven't been able to get the
natural seeming syntax to even compile.  The below code compiles but doesn't
produce the desired results because my overloaded operator() doesn't get
called.  The actual results indicate that the string > operator is the one
that's called.

So what am I doing wrong?  Where can I find an example of this technique?
Any help would be greatly appreciated!

// File: SortTest.cpp

#pragma warning(disable:4786)

#include <iostream>
#include <string>
#include <list>
using namespace std;

struct longer : public greater <string>
  {
  longer () {};
  bool operator() (const string& x, const string& y) const
    { return x.length () > y.length (); };
  };

void PrintOut (string str, list <string> theList)
  {
  list <string>::iterator i;
  cout << endl << str << endl << endl;
  for (i=theList.begin (); i!=theList.end (); ++i)
    cout << *i << endl;
  }

int main (int argc, char* argv[])
  {
  list <string> listStuff;

  listStuff.push_back ("qwerty");
  listStuff.push_back ("asdf");
  listStuff.push_back ("this is a test");
  listStuff.push_back ("do not pass GO!");
  listStuff.push_back ("do not collect $200");
  listStuff.push_back ("this is");
  listStuff.push_back ("only a test");

  PrintOut ("Original list", listStuff);

  longer x;
  listStuff.sort (x);

  PrintOut ("List sorted on length", listStuff);

 return 0;
  }



Sat, 04 Aug 2001 03:00:00 GMT  
 std::list<string>::sort (Cmp)
I dont know much about this but the following works for me. I didn't think
that the sort algorithm would use
the overloaded ().

Try this

#include <vector>
#include <algorithm>
#include <functional>
#include <stdlib.h>

class ID
{
public:
 ID(char letter='z',int number=0){m_letter=letter;m_number=number;}
 bool operator<( const ID& id);
 bool operator==(const ID& id);
 virtual ~ID(){}

 char m_letter;
 int m_number;

Quote:
};

bool ID::operator <(const ID& id)
{
 return (m_number<id.m_number);

Quote:
}

bool ID::operator ==(const ID& id)
{
 return (m_number==id.m_number);

Quote:
}

int main()
{

 std::vector<ID> myVect;
 for (int n=0;n<20;n++)
  myVect.push_back(ID((char)(100+((float)rand()/0x7fff)*100),
  rand()
  ));

 for (n=0;n<20;n++)
  printf("%c ,%i \n",myVect[n].m_letter,myVect[n].m_number);

 std::sort( myVect.begin( ), myVect.end( ),std::less<ID>);
 for (n=0;n<20;n++)
  printf("%c ,%i \n",myVect[n].m_letter,myVect[n].m_number);

 return 1;

Quote:
}
}

>I'm trying to understand the mechanism to sort a list in several different
>ways.  For instance, if I have a list of stings, I may want to sort the
list
>alphabetically, by length, by some known substring or by who knows what.
>I've been reading Stroustrop (C++ Programming Language 3rd Edition) and
>Deitel & Deitel (C++ How to Program) and both of these books indicate that
>this should be an easy thing to do.  Well, I haven't been able to get the
>natural seeming syntax to even compile.  The below code compiles but
doesn't
>produce the desired results because my overloaded operator() doesn't get
>called.  The actual results indicate that the string > operator is the one
>that's called.

>So what am I doing wrong?  Where can I find an example of this technique?
>Any help would be greatly appreciated!

>// File: SortTest.cpp

>#pragma warning(disable:4786)

>#include <iostream>
>#include <string>
>#include <list>
>using namespace std;

>struct longer : public greater <string>
>  {
>  longer () {};
>  bool operator() (const string& x, const string& y) const
>    { return x.length () > y.length (); };
>  };

>void PrintOut (string str, list <string> theList)
>  {
>  list <string>::iterator i;
>  cout << endl << str << endl << endl;
>  for (i=theList.begin (); i!=theList.end (); ++i)
>    cout << *i << endl;
>  }

>int main (int argc, char* argv[])
>  {
>  list <string> listStuff;

>  listStuff.push_back ("qwerty");
>  listStuff.push_back ("asdf");
>  listStuff.push_back ("this is a test");
>  listStuff.push_back ("do not pass GO!");
>  listStuff.push_back ("do not collect $200");
>  listStuff.push_back ("this is");
>  listStuff.push_back ("only a test");

>  PrintOut ("Original list", listStuff);

>  longer x;
>  listStuff.sort (x);

>  PrintOut ("List sorted on length", listStuff);

> return 0;
>  }



Sun, 05 Aug 2001 03:00:00 GMT  
 std::list<string>::sort (Cmp)

Quote:

>          The actual results indicate that the string > operator is the one
> that's called.

And, so it is.

It comes from the following code in the <list> header:

// ======================================================
typedef greater<_Ty> _Pr3;

void sort(_Pr3 _Pr)
{
// [most bits omitted for space saving]

while (0 < _N)
  merge(_A[--_N], _Pr);

Quote:
}

void merge(_Myt& _X, _Pr3 _Pr)
{
// [more omissions for clarity]

iterator _F1 = begin(), _L1 = end();
iterator _F2 = _X.begin(), _L2 = _X.end();

if (_Pr(*_F2, *_F1))
// [still more omissions]

Quote:
}

// ======================================================

Thus, the version of sort that takes a parameter, always uses greater<_Ty> as
the comparison function.

The documentation says this is because:

"...if a translator does not support member template functions, the template:

template<class Pred> void sort(Pred pr);

is replaced by:

void sort(greater<T> pr);"

Well, I thought MSVC++ 6.0 supported template member functions as long as
they were included in the class definition, as these are.  I guess they
haven't gotten around to editing the STL to conform with the compiler.

--
Jeff Rife                   | "Maybe it won't be so bad.  Just think what life
19445 Saint Johnsbury Lane  |  would be like without Tiffany."
Germantown, MD  20876-1610  | "We'd be unemployed!  We're on the WB *with* her!"
Home: 301-916-8131          |              -- Ryan and Jack Malloy, "...Unhappily Ever After"
Work: 301-770-5800 Ext 5335 |  



Sun, 05 Aug 2001 03:00:00 GMT  
 std::list<string>::sort (Cmp)
Thanks for the help!  I fixed my actual problem by using a vector instead of
a list, a vector actually is what I needed to be using anyway.  And by using
the algorithm sort on the vector rather than the sort function that's a list
member.

But I still don't understand why the list.sort (cmp) method doesn't work.
Should I conclude that it's an STL bug?

Quote:

>the following works for me.

>#include <vector>
>#include <algorithm>
> ...
> std::sort( myVect.begin( ), myVect.end( ),std::less<ID>);


Quote:
> Well, I thought MSVC++ 6.0 supported template member functions
> as long as they were included in the class definition, as these are.
> I guess they haven't gotten around to editing the STL to conform with
> the compiler.



Tue, 07 Aug 2001 03:00:00 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. std::list<string>::sort (Cmp)

2. Warnings for std::vector<std::string>

3. typedef std::vector<std::string> Vector_String

4. <<<>>>Need C code advice with functions and sorting.<<<>>>

5. How can I sort a std::list< std::string >

6. <<<<<<<Parsing help, please>>>>>>>>

7. std::list<> problem

8. Problems with std::list<E>::iterator which requires that E is defines vc++

9. std::list<>::iterator problem

10. vector<std::string>

11. STL <list> and sort(Pred pr)

12. list::sort() and greater<T>

 

 
Powered by phpBB® Forum Software