0

I have a map composed by a key (type string) and data (type tuple). I tried to sort my map using a lambda (see code below) but when I compile I got error saying

Severity Code Description Project File Line Suppression State Error C2676 binary '-': 'const std::_Tree_unchecked_iterator>>>' does not define this operator or a conversion to a type acceptable to the predefined operator with [ _Kty=std::string, _Ty=std::tuple ] SandBox C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.23.28105\include\algorithm 3466

Severity Code Description Project File Line Suppression State Error C2672 '_Sort_unchecked': no matching overloaded function found SandBox C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.23.28105\include\algorithm 3466

My Code:

#include <iostream>
#include <string>
#include <tuple>
#include <map>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;


int main() {
    std::vector<std::string> strarr { "zone", "abigail", "theta", "form", "libe", "zas", "theta", "abigail"};

    int length = strarr.size();

    std::string str = "";

    map<string, tuple<int, int>> myMap;

    for (int i = 0; i < length; i++)
        myMap[strarr[i]] = make_tuple(strarr[i].length(), ++(get<1>(myMap[strarr[i]])));


    typedef std::function<bool(std::pair<string, tuple< int, int >>, std::pair<string, tuple< int, int >>)> Comparator;

    Comparator compFunctor =
        [](std::pair<string,tuple< int, int>> el1, std::pair<string, tuple< int, int >> el2)
    {
        return (get<0>(el1.second) < get<0>(el2.second));
    };

    std::sort(myMap.begin(), myMap.end(), compFunctor);
}

So what is the error ? I am sure that it is something silly but can't figure it out by my own.

Thank you in advance.

Blood-HaZaRd
  • 2,049
  • 2
  • 20
  • 43
  • The std::map automatically sorts by key, so you cannot sort that map by value. What you need is a second map that is flipped. You then have two maps, which can be contained in a "multimap", as shown at https://stackoverflow.com/a/5056797/5652483 – Scott Hutchinson Nov 10 '19 at 17:26
  • Another name for multimap is a "BiMap". See an implementation at https://gist.github.com/ScottHutchinson/e63d19b60445db4e91669a198817f066 – Scott Hutchinson Nov 13 '19 at 23:41

2 Answers2

4

Your error is that std::sort requires a random access iterator but the iterator of a std::map is a bidirectional iterator. You will see that operator-() is not defined for a bidrectional iterators

see type requirements here.

Further to this, what you are doing seems odd. It looks like you are trying to sort a map based on the first element of its value. A map is implicitly sorted using (by default) std::less on the key type. If you want to sort in a different order you should use a custom comparator on the map.

rmawatson
  • 1,909
  • 12
  • 20
1

std::map is a red-black tree. You cannot sort it by value. If you want your map to be sorted by value, you need to flip it.

struct compFunctor{
bool operator()(tuple< int, int> el1, tuple< int, int > el2) const {
     return get<0>(el1) < get<0>(el2);
}
};

map< tuple<int, int>, string, compFunctor> myMap:
Oblivion
  • 7,176
  • 2
  • 14
  • 33
  • This is not gonna work. `compFunctor` can be used for comparing `pair>`, but `myMap` requires something that can compare `pair, string>`. – Fureeish Nov 10 '19 at 14:31