1

So I'm having some trouble figuring out the proper use of list::sort() in regards to a list of structs. Heres the relevant code:

struct student
{
    char firstnm[20],   
        lastnm[20];     
    int id,             
        grade;
};
list<student> sList;

//Irrelevant code...

cout << "Please enter your own name, id, and grade. (Ex: myfirst mylast 0 12)\n";
cin >> data.firstnm >> data.lastnm >> data.id >> data.grade;
sList.push_back(data);
sList.sort();

The problem I'm trying to solve is using sList.sort() to sort by id. However, I have no idea how to properly pass it into list::sort(). Thanks in advance for any help/time!

EDIT: The solution was simply adding this to my struct

bool operator < (const student& cmp) const {
   return id < cmp.id;
}
JFMR
  • 23,265
  • 4
  • 52
  • 76
k seaner
  • 35
  • 3

2 Answers2

2

The member function std::list::sort() is overloaded. std::list has an ordinary member function that takes no parameters and uses operator< for sorting the elements of the list:

void sort();

It also has a member function template taking one parameter comp that is used as the predicate for sorting the elements:

template<class Compare> 
void sort(Compare comp);

Assuming you want to sort the student objects in your list according to the key id in ascending order. You can either define operator< for your user-defined student class as:

bool operator<(student const& a, student const& b) {
   return a.id < b.id;
}

and use the overload that takes no parameters:

sList.sort(); // 1st overload

or simply plass a lambda expression to the member function template taking one parameter:

auto cmp = [](auto const& a, auto const& b) {
   return a.id < b.id;
}; 

sList.sort(cmp); // 2nd overload

with this approach, you don't need to define operator< for your student class.


Note that you can't use the std::sort() algorithm on std::list's iterators, because this algorithm requires random-access iterators, but an std::list only provides bidirectional iterators. Therefore, the following code won't compile:

std::sort(sList.begin(), sList.end());

Instead, you have to use the member functions provided by std::list in order to sort the elements of the container as explained above.

JFMR
  • 23,265
  • 4
  • 52
  • 76
0

You should give a look to std::sort. (https://en.cppreference.com/w/cpp/algorithm/sort) There is multiple definitions of that function, and one where you can specify on what you want to sort.

Also, give a look to that post, I think it's what you need : https://stackoverflow.com/a/21234017/6663947

Edit :

thats an exemple of comparator :

sList.sort([](const student & a, const student & b) { return a.id < b.id; });

I did not tried it, but it should look like it. Also, this is for c++11

Hope it helps!

Francis Robitaille
  • 575
  • 1
  • 5
  • 18
  • Thank you! I think you're right. I'll start playing around with it. So what you're saying though is I'll need to use the sort from #include after creating an overload for a lessthan operation, rather than the one supplied by the STL? – k seaner Mar 17 '19 at 19:04
  • Yeah, so you need to add a comparator. You could also use the sList.sort() like you did, but with the comparator as parameter... – Francis Robitaille Mar 17 '19 at 19:21
  • 1
    @kseaner You don't have to use the `sort` from the `` header or include it at all. You only have to pass your definition of `less` either as a function, a function object or a lambda. You could also define `operator<` for you `student`-type and don't pass anything to `sort` – sv90 Mar 17 '19 at 19:31
  • 2
    @kseaner Note that you can't use `std::sort` from `` to sort a `std::list`. It requires random-access iterators and won't compile if you give it `std::list` iterators. That's why `std::list::sort` exists. – Blastfurnace Mar 18 '19 at 08:05