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