Topic: Binary predicate for deque<> and list<>


Author: "sujh" <suj_h@yahoo.com>
Date: 2000/01/22
Raw View
The following example compiles and runs. However, if you substitute deque
with list, it generates something like thousand lines of error message.
Why? How can you make it work?

// inspired by Josuttis
#include <iostream>
#include <string>
#include <deque>
#include <set>
#include <algorithm>

class Person
{
 std::string name;
 int id;
public:
 Person(const char *in_name, int in_id): name(in_name), id(in_id) {};
 std::string getname() const { return name; };
 int getid() const { return id;};
 friend std::ostream&
  operator<<( std::ostream& os, Person& p)
 { os << "[" << p.id << " " << p.name << "]"; return os; };
};

/* binary function predicate:
 * - returns whether a person is less than another person
 */
bool personSortByName (const Person& p1, const Person& p2)
{
    return ( p1.getname() <p2.getname() )? true:false;
}

/* binary function predicate:
 * - returns whether a person is less than another person
 */
bool personSortById (const Person& p1, const Person& p2)
{
    return ( p1.getid() <p2.getid() )? true:false;
}

int main()
{
 Person p1("jack",234),p2("zomba",123),p3("anica",100);
    Person p4("josuttis",99);
    Person p5("lucas",810);
    Person p6("lucas",777);
    Person p7("anica",315);

 std::deque<Person> coll;
 coll.push_back(p1);
 coll.push_back(p2);
 coll.push_back(p3);
    coll.push_back(p4);
    coll.push_back(p5);
    coll.push_back(p6);
    coll.push_back(p7);

    // print elements
    std::cout << "before sort():" << std::endl;
    std::deque<Person>::iterator pos;
    for (pos = coll.begin(); pos != coll.end(); ++pos) {
        std::cout << *pos << std::endl;
    }

 // sort by id
 std::sort(coll.begin(),coll.end(),
  personSortById);

 // print elements
    std::cout << "after sort with id:" << std::endl;
    for (pos = coll.begin(); pos != coll.end(); ++pos) {
        std::cout << *pos << std::endl;
    }

 // sort by name
 std::sort(coll.begin(),coll.end(),
  personSortByName);

 // print elements
    std::cout << "after sort with name:" << std::endl;
    for (pos = coll.begin(); pos != coll.end(); ++pos) {
        std::cout << *pos << std::endl;
    }
 return 0;
}

--+su+--
http://www.geocities.com/cpu8031/

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James Kuyper <kuyper@wizard.net>
Date: 2000/01/23
Raw View
sujh wrote:
>
> The following example compiles and runs. However, if you substitute deque
> with list, it generates something like thousand lines of error message.
> Why? How can you make it work?
....
>         std::deque<Person> coll;
....
>         std::sort(coll.begin(),coll.end(),
>                 personSortByName);

std::sort() requires random access iterators. std::deque::iterator is a
random access iterator, but std::list<>::iterator is only bidirectional.

To sort your list, use coll.sort(), not std::sort().

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Chris Newton" <chrisnewton@dont.spam.me.callnetuk.com>
Date: 2000/01/23
Raw View
sujh <suj_h@yahoo.com> wrote...
> The following example compiles and runs. However, if
> you substitute deque with list, it generates something
> like thousand lines of error message. Why? How can
> you make it work?
[...]
> std::deque<Person> coll;
[...]
> std::sort(coll.begin(),coll.end(), personSortById);

The problem here seems to be that the generic std::sort algorithm
requires *random access* iterators as parameters. std::deque supports
random access iterators, but std::list does not. As a result, the above
is fine, but the std::sort algorithm cannot be used on a std::list.

Fortunately, the library designers saw this coming, and implemented a
sort method for the list container separately. To fix your problem,
you'll need to replace the above lines with something like
  std::list<Person> coll;
  [...]
  coll.sort(personSortById);

Hope that helps,
Chris

[Followup-To set to alt.comp.lang.learn.c-c++ only.]


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Joseph Gottman" <joegottman@worldnet.att.net>
Date: 2000/01/23
Raw View
sujh <suj_h@yahoo.com> wrote in message
news:01bf5f44$3728f870$70a6490c@aristotle...
> The following example compiles and runs. However, if you substitute deque
> with list, it generates something like thousand lines of error message.
> Why? How can you make it work?

   All but relevant code snipped.
>
> std::deque<Person> coll;
   Add some data.

> std::sort(coll.begin(),coll.end(),
> personSortByName);
>


  std::sort() requires random-access iterators.  Lists only have
bidirectional iterators (i.e there is no operator []() ).  Replace
std::sort(coll.begin(), coll.end(), personSortByName) with
coll.sort(personSortByName);

Joe Gottman


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Martin Ambuhl <mambuhl@earthlink.net>
Date: 2000/01/23
Raw View

sujh wrote:
>
> The following example compiles and runs. However, if you substitute deque
> with list, it generates something like thousand lines of error message.
> Why? How can you make it work?

You mean :%s/deque/list/

lists take special form of sort (and split and merge) specially suited
to list structure.  See the blocks of code with the tell-tale /* mha */
commnets below.  And you should have gotten many fewer lines of error
message than you are reporting.

#include <iostream>
#include <string>
#include <list>
#include <set>
#include <algorithm>

class Person
{
    std::string name;
    int id;
  public:
     Person(const char *in_name, int in_id):name(in_name), id(in_id)
    {
    };
    std::string getname()const
    { return name;
    };
    int getid() const
    { return id;
    };
    friend std::ostream & operator << (std::ostream & os, Person & p)
    {
        os << "[" << p.id << " " << p.name << "]";
        return os;
    };
};

/* binary function predicate:
 * - returns whether a person is less than another person
 */
bool personSortByName(const Person & p1, const Person & p2)
{
    return (p1.getname() < p2.getname())? true : false;
}

/* binary function predicate:
 * - returns whether a person is less than another person
 */
bool personSortById(const Person & p1, const Person & p2)
{
    return (p1.getid() < p2.getid())? true : false;
}

int main()
{
    Person p1("jack", 234), p2("zomba", 123), p3("anica", 100);
    Person p4("josuttis", 99);
    Person p5("lucas", 810);
    Person p6("lucas", 777);
    Person p7("anica", 315);

    std::list < Person > coll;
    coll.push_back(p1);
    coll.push_back(p2);
    coll.push_back(p3);
    coll.push_back(p4);
    coll.push_back(p5);
    coll.push_back(p6);
    coll.push_back(p7);

    // print elements
    std::cout << "before sort():" << std::endl;
    std::list < Person >::iterator pos;
    for (pos = coll.begin(); pos != coll.end(); ++pos) {
        std::cout << *pos << std::endl;
    }

/* mha - changes here */
#if 0
    // sort by id
    std::sort(coll.begin(), coll.end(), personSortById);
#endif
    coll.sort(personSortById);

    // print elements
    std::cout << "after sort with id:" << std::endl;
    for (pos = coll.begin(); pos != coll.end(); ++pos) {
        std::cout << *pos << std::endl;
    }

/* mha - changes here */
#if 0
    // sort by name
    std::sort(coll.begin(), coll.end(), personSortByName);
#endif
    coll.sort(personSortByName);

    // print elements
    std::cout << "after sort with name:" << std::endl;
    for (pos = coll.begin(); pos != coll.end(); ++pos) {
        std::cout << *pos << std::endl;
    }
    return 0;
}



before sort():
[234 jack]
[123 zomba]
[100 anica]
[99 josuttis]
[810 lucas]
[777 lucas]
[315 anica]
after sort with id:
[99 josuttis]
[100 anica]
[123 zomba]
[234 jack]
[315 anica]
[777 lucas]
[810 lucas]
after sort with name:
[100 anica]
[315 anica]
[234 jack]
[99 josuttis]
[777 lucas]
[810 lucas]
[123 zomba]


--
Martin Ambuhl mambuhl@earthlink.net

What one knows is, in youth, of little moment; they know enough who
know how to learn. - Henry Adams

A thick skin is a gift from God. - Konrad Adenauer
__________________________________________________________
Fight spam now!
Get your free anti-spam service: http://www.brightmail.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]