16

While practicing the use of lambdas, I wrote this program which is supposed to sort a list of pairs by their second element (an int).

#include <iostream>
#include <algorithm>
#include <list>

using namespace std;
int main()
{
    list<pair <string, int>> s = {{"two", 2}, {"one", 1}, {"three", 3}};

    sort(s.begin(), s.end(), [](pair<string,int> a, pair<string, int> b) -> bool {
        return (a.second) > (b.second);
    });

    for_each(s.begin(), s.end(), [](pair<string, int> a) {
        cout << a.first << " " << a.second << endl;
    });
}

I get those errors, though:

c:\qt\qt5.2.0\tools\mingw48_32\lib\gcc\i686-w64-mingw32\4.8.0\include\c++\bits\stl_algo.h:5513: error: no match for 'operator-' (operand types are 'std::_List_iterator<std::pair<std::basic_string<char>, int> >' and 'std::_List_iterator<std::pair<std::basic_string<char>, int> >')
     std::__lg(__last - __first) * 2, __comp);
                  ^

c:\qt\qt5.2.0\tools\mingw48_32\lib\gcc\i686-w64-mingw32\4.8.0\include\c++\bits\stl_algo.h:2245: ошибка: 'void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = std::_List_iterator<std::pair<std::basic_string<char>, int> >; _Compare = main()::__lambda0]', declared using local type 'main()::__lambda0', is used but never defined [-fpermissive]
     __final_insertion_sort(_RandomAccessIterator __first,
     ^

What is wrong with my code?

2 Answers 2

26

You may not use std::sort with sequential containers such as std::list or std::forward_list because they have no random access iterator that is required by the standard algorithm std::sort. By this reason the both containers have their own member functions sort.

In you case the code will look the following way:

#include <iostream>
#include <list>
#include <string>

using namespace std;

int main()
{
    list<pair <string, int>> s = {{"two", 2}, {"one", 1}, {"three", 3}};
    s.sort( []( const pair<string,int> &a, const pair<string,int> &b ) { return a.second > b.second; } );

    for ( const auto &p : s )
    {
        cout << p.first << " " << p.second << endl;
    }
}

Take into account that you need to include header <string> otherwise your program will not be compiled with other compilers.

Sign up to request clarification or add additional context in comments.

Comments

13

std::sort requires random access iterators, which std::list does not have. But you can use std::list::sort instead.

s.sort([](const pair<string,int>& a, const pair<string,int>& b)
       {
         return (a.second) > (b.second);
       });

where I have made the parameters of the predicate const references, since there is no need to copy them, and doing so might incur some unnecessary overhead.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.