1
#include <iostream>
#include <map>
#include <utility>
#include <algorithm>


int main()
{
        std::map<int, std::string> m;
        m[2] = "abc";
        m[1] = "bcd";

        auto cmp = [](std::pair<int, std::string>  a, std::pair<int, std::string>  b)
        {
                return a.second != b.second ? a.second < b.second : a.first < b.first;
        };
        std::sort(m.begin(), m.end(), cmp);
        for (auto it = m.begin(); it != m.end(); ++it)
        {
                std::cout<<it->first<<std::endl;
                std::cout<<it->second<<std::endl;
        }

        return 0;
}

I want to sort a map by its value, instead of its key, so I code as above.

I just read this link and this is why I code like this: std::map, how to sort by value, then by key

But it produced an error:

Severity    Code    Description Project File    Line    Suppression State
Error   C2784   'unknown-type std::operator -(const std::move_iterator<_RanIt> &,const std::move_iterator<_RanIt2> &)': could not deduce template argument for 'const std::move_iterator<_RanIt> &' from 'std::_Tree_unchecked_iterator<_Mytree>'   testcpp c:\program files (x86)\microsoft visual studio\2017\enterprise\vc\tools\msvc\14.10.25017\include\algorithm  2908
Yves
  • 11,597
  • 17
  • 83
  • 180
  • 2
    You should probably re-read the link. –  Apr 21 '18 at 11:46
  • 3
    Note that the linked question sorts a `vector`, not a `map`. A map is already sorted on the key to support fast lookup and cannot be reordered. (The specific error message comes from `std::sort` requiring a random access iterator, which the map doesn't have). – Bo Persson Apr 21 '18 at 12:39
  • 2
    `std::map` is a sorted container; and is sorted according the key (the first type of the couple); you can change the sorting function (using the third, defaulted template parameter of `std::map`) but there is no sense in sorting it using `std::sort`. – max66 Apr 21 '18 at 12:46

1 Answers1

3
auto cmp = [](std::pair<int, std::string>  a, std::pair<int, std::string>  b)
    {
            return a.second != b.second ? a.second < b.second : a.first < b.first;
    };

Here's the problem.

The predicate's parameter should have the type that key_type can convert to implicitly

And you shouldn't apply std::sort to std::map. One reason is this operation is redundant(see the reference below), another is the keys have const type.

http://en.cppreference.com/w/cpp/container/map

And another advice:

declare the predicate's parameter type as a reference to const

con ko
  • 1,368
  • 5
  • 18