vendredi 20 octobre 2023

Error in custom comparator for multimap stl c++11


I am trying to run the following code where I create the multimap structure with key and value as pair of two integer values.
I want the stucture to be sorted (without using explicit sorting technique) after each insertion in a way where string is in ascending order, descending order by value's first part and ascending by value's second part.
I wrote the code below for which compilation fails.
#include <iostream>
#include <map>
#include <string>

struct CustomComparator {
    bool operator()(const std::pair<std::string, std::pair<int, int>>& lhs, const std::pair<std::string, std::pair<int, int>>& rhs)  {
        if (lhs.first < rhs.first) {
            return true;  // Sort by key in ascending order
        }
        if (lhs.first > rhs.first) {
            return false; // Sort by key in descending order
        }
        // If keys are equal, sort by the value's first key in descending order
        if (lhs.second.first > rhs.second.first) {
            return true;
        }
        if (lhs.second.first < rhs.second.first) {
            return false;
        }
        // If both keys and the first value's key are equal, sort by the value's second value in ascending order
        return lhs.second.second < rhs.second.second;
    }
};

int main() {
    std::multimap<std::string, std::pair<int, int>, CustomComparator> keyValueMultimap;

    keyValueMultimap.insert({"Apple", {3, 5}});
    keyValueMultimap.insert({"Banana", {2, 4}});
    keyValueMultimap.insert({"Apple", {1, 2}});
    keyValueMultimap.insert({"Orange", {4, 6}});

    for (const auto& pair : keyValueMultimap) {
        std::cout << "Key: " << pair.first << ", Value: (" << pair.second.first << ", " << pair.second.second << ")" << std::endl;
    }

    return 0;
}


Looking out for help.
Thanks in advance.

Note: Trying to compile using C++11 version.

Resulted in following console log:

Compilation failed due to following error(s).
In file included from /usr/include/c++/11/map:60,
                 from main.cpp:2:
/usr/include/c++/11/bits/stl_tree.h: In instantiation of ‘std::pair<std::_Rb_tree_node_base*, std::_Rb_tree_node_base*> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_get_insert_equal_pos(const key_type&) [with _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> >; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >; _Compare = CustomComparator; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::key_type = std::__cxx11::basic_string<char>]’:
/usr/include/c++/11/bits/stl_tree.h:2151:4:   required from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_equal(_Arg&&) [with _Arg = std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> >; _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> >; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >; _Compare = CustomComparator; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree<std::__cxx11::basic_string<char>, std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> >, std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >, CustomComparator, std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > > >::iterator]’
/usr/include/c++/11/bits/stl_multimap.h:547:36:   required from ‘std::multimap<_Key, _Tp, _Compare, _Alloc>::iterator std::multimap<_Key, _Tp, _Compare, _Alloc>::insert(std::multimap<_Key, _Tp, _Compare, _Alloc>::value_type&&) [with _Key = std::__cxx11::basic_string<char>; _Tp = std::pair<int, int>; _Compare = CustomComparator; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >; std::multimap<_Key, _Tp, _Compare, _Alloc>::iterator = std::_Rb_tree<std::__cxx11::basic_string<char>, std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> >, std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >, CustomComparator, std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > > >::iterator; std::multimap<_Key, _Tp, _Compare, _Alloc>::value_type = std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> >]’
main.cpp:28:28:   required from here
/usr/include/c++/11/bits/stl_tree.h:2102:39: error: no match for call to ‘(CustomComparator) (const key_type&, const std::__cxx11::basic_string&)’
 2102 |           __x = _M_impl._M_key_compare(__k, _S_key(__x)) ?
      |                 ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
main.cpp:6:10: note: candidate: ‘bool CustomComparator::operator()(const std::pair, std::pair >&, const std::pair, std::pair >&)’
    6 |     bool operator()(const std::pair<std::string, std::pair<int, int>>& lhs, const std::pair<std::string, std::pair<int, int>>& rhs)  {
      |          ^~~~~~~~
main.cpp:6:72: note:   no known conversion for argument 1 from ‘const key_type’ {aka ‘const std::__cxx11::basic_string’} to ‘const std::pair, std::pair >&’
    6 |     bool operator()(const std::pair<std::string, std::pair<int, int>>& lhs, const std::pair<std::string, std::pair<int, int>>& rhs)  {
      |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
In file included from /usr/include/c++/11/map:60,
                 from main.cpp:2:
/usr/include/c++/11/bits/stl_tree.h: In instantiation of ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr, _Arg&&, _NodeGen&) [with _Arg = std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> >; _NodeGen = std::_Rb_tree<std::__cxx11::basic_string<char>, std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> >, std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >, CustomComparator, std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > > >::_Alloc_node; _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> >; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >; _Compare = CustomComparator; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree<std::__cxx11::basic_string<char>, std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> >, std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >, CustomComparator, std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > > >::iterator; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr = std::_Rb_tree_node_base*]’:
/usr/include/c++/11/bits/stl_tree.h:2153:24:   required from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_equal(_Arg&&) [with _Arg = std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> >; _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> >; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >; _Compare = CustomComparator; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree<std::__cxx11::basic_string<char>, std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> >, std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >, CustomComparator, std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > > >::iterator]’
/usr/include/c++/11/bits/stl_multimap.h:547:36:   required from ‘std::multimap<_Key, _Tp, _Compare, _Alloc>::iterator std::multimap<_Key, _Tp, _Compare, _Alloc>::insert(std::multimap<_Key, _Tp, _Compare, _Alloc>::value_type&&) [with _Key = std::__cxx11::basic_string<char>; _Tp = std::pair<int, int>; _Compare = CustomComparator; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >; std::multimap<_Key, _Tp, _Compare, _Alloc>::iterator = std::_Rb_tree<std::__cxx11::basic_string<char>, std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> >, std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >, CustomComparator, std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > > >::iterator; std::multimap<_Key, _Tp, _Compare, _Alloc>::value_type = std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> >]’
main.cpp:28:28:   required from here
/usr/include/c++/11/bits/stl_tree.h:1781:56: error: no match for call to ‘(CustomComparator) (std::pair, std::pair >::first_type&, const std::__cxx11::basic_string&)’
 1781 |                               || _M_impl._M_key_compare(_KeyOfValue()(__v),
      |                                  ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
 1782 |                                                         _S_key(__p)));
      |                                                         ~~~~~~~~~~~~
main.cpp:6:10: note: candidate: ‘bool CustomComparator::operator()(const std::pair, std::pair >&, const std::pair, std::pair >&)’
    6 |     bool operator()(const std::pair<std::string, std::pair<int, int>>& lhs, const std::pair<std::string, std::pair<int, int>>& rhs)  {
      |          ^~~~~~~~
main.cpp:6:72: note:   no known conversion for argument 1 from ‘std::pair, std::pair >::first_type’ {aka ‘const std::__cxx11::basic_string’} to ‘const std::pair, std::pair >&’
    6 |     bool operator()(const std::pair<std::string, std::pair<int, int>>& lhs, const std::pair<std::string, std::pair<int, int>>& rhs)  {
      |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
In file included from /usr/include/c++/11/map:60,
                 from main.cpp:2:
/usr/include/c++/11/bits/stl_tree.h: In instantiation of ‘static const _Key& std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_S_key(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Const_Link_type) [with _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> >; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >; _Compare = CustomComparator; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Const_Link_type = const std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >*]’:
/usr/include/c++/11/bits/stl_tree.h:2102:44:   required from ‘std::pair<std::_Rb_tree_node_base*, std::_Rb_tree_node_base*> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_get_insert_equal_pos(const key_type&) [with _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> >; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >; _Compare = CustomComparator; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::key_type = std::__cxx11::basic_string<char>]’
/usr/include/c++/11/bits/stl_tree.h:2151:4:   required from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_equal(_Arg&&) [with _Arg = std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> >; _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> >; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >; _Compare = CustomComparator; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree<std::__cxx11::basic_string<char>, std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> >, std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >, CustomComparator, std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > > >::iterator]’
/usr/include/c++/11/bits/stl_multimap.h:547:36:   required from ‘std::multimap<_Key, _Tp, _Compare, _Alloc>::iterator std::multimap<_Key, _Tp, _Compare, _Alloc>::insert(std::multimap<_Key, _Tp, _Compare, _Alloc>::value_type&&) [with _Key = std::__cxx11::basic_string<char>; _Tp = std::pair<int, int>; _Compare = CustomComparator; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >; std::multimap<_Key, _Tp, _Compare, _Alloc>::iterator = std::_Rb_tree<std::__cxx11::basic_string<char>, std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> >, std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > >, CustomComparator, std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> > > >::iterator; std::multimap<_Key, _Tp, _Compare, _Alloc>::value_type = std::pair<const std::__cxx11::basic_string<char>, std::pair<int, int> >]’
main.cpp:28:28:   required from here
/usr/include/c++/11/bits/stl_tree.h:762:23: error: static assertion failed: comparison object must be invocable with two arguments of key type
  762 |         static_assert(__is_invocable<_Compare&, const _Key&, const _Key&>{},
      |                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/11/bits/stl_tree.h:762:23: note: ‘std::__is_invocable, std::allocator >&, const std::__cxx11::basic_string, std::allocator >&>{}’ evaluates to false

Aucun commentaire:

Enregistrer un commentaire