Overloading && for `std::variant` breaks an unrelated `std::map` - c++

(This question was originally asked by a different user at Russian SO. I'm reposting it here with minor changes to give it more exposure.)
Consider this code:
#include <map>
#include <variant>
void operator&&(std::variant<int>, std::variant<int>) {}
int main()
{
std::map<int, int> vals;
vals.find(42);
}
Clang (with both libstdc++ and libc++) and MSVC compile it without problems.
Hovewer, GCC 11.1 and newer (including trunk) give this: Run on gcc.godbolt.org
In file included from /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/bits/move.h:57,
from /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/bits/stl_pair.h:59,
from /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/bits/stl_algobase.h:64,
from /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/bits/stl_tree.h:63,
from /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/map:60,
from <source>:1:
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/type_traits: In instantiation of 'struct std::is_invocable<const std::less<int>&, const int&, const int&>':
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/type_traits:3001:73: required from 'constexpr const bool std::is_invocable_v<const std::less<int>&, const int&, const int&>'
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/bits/stl_tree.h:770:8: required from '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 = int; _Val = std::pair<const int, int>; _KeyOfValue = std::_Select1st<std::pair<const int, int> >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, int> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Const_Link_type = const std::_Rb_tree_node<std::pair<const int, int> >*]'
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/bits/stl_tree.h:1903:36: required from 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_lower_bound(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr, const _Key&) [with _Key = int; _Val = std::pair<const int, int>; _KeyOfValue = std::_Select1st<std::pair<const int, int> >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, int> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree<int, std::pair<const int, int>, std::_Select1st<std::pair<const int, int> >, std::less<int>, std::allocator<std::pair<const int, int> > >::iterator; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const int, int> >*; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr = std::_Rb_tree_node_base*]'
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/bits/stl_tree.h:2521:36: required from 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::find(const _Key&) [with _Key = int; _Val = std::pair<const int, int>; _KeyOfValue = std::_Select1st<std::pair<const int, int> >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, int> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree<int, std::pair<const int, int>, std::_Select1st<std::pair<const int, int> >, std::less<int>, std::allocator<std::pair<const int, int> > >::iterator]'
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/bits/stl_map.h:1170:25: required from 'std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::find(const key_type&) [with _Key = int; _Tp = int; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::iterator = std::_Rb_tree<int, std::pair<const int, int>, std::_Select1st<std::pair<const int, int> >, std::less<int>, std::allocator<std::pair<const int, int> > >::iterator; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = int]'
<source>:9:14: required from here
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/type_traits:2942:7: error: ambiguous overload for 'operator&&' (operand types are 'std::true_type' {aka 'std::integral_constant<bool, true>'} and 'std::true_type' {aka 'std::integral_constant<bool, true>'})
2942 | static_assert((std::__is_complete_or_unbounded(
| ^~~~~~~~~~~~~
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/type_traits:2942:7: note: candidate: 'operator&&(std::integral_constant<bool, true>::value_type {aka bool}, std::integral_constant<bool, true>::value_type {aka bool})' (built-in)
<source>:4:6: note: candidate: 'void operator&&(std::variant<int>, std::variant<int>)'
4 | void operator &&(std::variant<int>, std::variant<int>) {}
| ^~~~~~~~
What's going on here?
EDIT:
Our operator== overload should be invisible for name lookup from <variant> (except for ADL, which is not involved here), so this is definitely a GCC bug.
#rustyx found GCC bug #51577, which looks very similar. But there's more to it, because that bug was introduced in GCC 4.7.0, while the code above only breaks and 11.1 and newer.

This was a GCC bug, fixed in GCC 12.

Related

Error using custom comparator for sorting map

I'm trying to sort the keys of a Sparse Matrix by row and column, and I want to use a map for this purpose. I added a custom comparator to ensure that, but I facing the following compilation error:
g++ -O2 -Wall -std=c++11 -Wextra -Wpedantic -c -o main.o main.cpp
In file included from /usr/include/c++/9/map:60,
from Matrix.hh:1,
from main.cpp:3:
/usr/include/c++/9/bits/stl_tree.h: In instantiation of ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::find(const _Key&) const [with _Key = std::pair<int, int>; _Val = std::pair<const std::pair<int, int>, int>; _KeyOfValue = std::_Select1st<std::pair<const std::pair<int, int>, int> >; _Compare = compare_keys; _Alloc = std::allocator<std::pair<const std::pair<int, int>, int> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const std::pair<int, int>, int> >]’:
/usr/include/c++/9/bits/stl_map.h:1215:31: required from ‘std::map<_Key, _Tp, _Compare, _Alloc>::size_type std::map<_Key, _Tp, _Compare, _Alloc>::count(const key_type&) const [with _Key = std::pair<int, int>; _Tp = int; _Compare = compare_keys; _Alloc = std::allocator<std::pair<const std::pair<int, int>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::size_type = long unsigned int; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::pair<int, int>]’
Matrix.hh:23:9: required from ‘bool Matrix<T>::emplace(int, int, T) [with T = int]’
main.cpp:7:5: required from here
/usr/include/c++/9/bits/stl_tree.h:2572:8: error: no match for call to ‘(const compare_keys) (const std::pair<int, int>&, const std::pair<int, int>&)’
2571 | return (__j == end()
| ~~~~~~~~~~~~~
2572 | || _M_impl._M_key_compare(__k,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2573 | _S_key(__j._M_node))) ? end() : __j;
| ~~~~~~~~~~~~~~~~~~~~~
In file included from main.cpp:3:
Matrix.hh:6:10: note: candidate: ‘bool compare_keys::operator()(const key&, const key&)’ <near match>
6 | bool operator() (const key& left_key, const key& right_key) {
| ^~~~~~~~
Matrix.hh:6:10: note: passing ‘const compare_keys*’ as ‘this’ argument discards qualifiers
In file included from /usr/include/c++/9/map:60,
from Matrix.hh:1,
from main.cpp:3:
/usr/include/c++/9/bits/stl_tree.h: In instantiation of ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_lower_bound(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Const_Link_type, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Const_Base_ptr, const _Key&) const [with _Key = std::pair<int, int>; _Val = std::pair<const std::pair<int, int>, int>; _KeyOfValue = std::_Select1st<std::pair<const std::pair<int, int>, int> >; _Compare = compare_keys; _Alloc = std::allocator<std::pair<const std::pair<int, int>, int> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const std::pair<int, int>, int> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Const_Link_type = const std::_Rb_tree_node<std::pair<const std::pair<int, int>, int> >*; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Const_Base_ptr = const std::_Rb_tree_node_base*]’:
/usr/include/c++/9/bits/stl_tree.h:2570:22: required from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::find(const _Key&) const [with _Key = std::pair<int, int>; _Val = std::pair<const std::pair<int, int>, int>; _KeyOfValue = std::_Select1st<std::pair<const std::pair<int, int>, int> >; _Compare = compare_keys; _Alloc = std::allocator<std::pair<const std::pair<int, int>, int> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const std::pair<int, int>, int> >]’
/usr/include/c++/9/bits/stl_map.h:1215:31: required from ‘std::map<_Key, _Tp, _Compare, _Alloc>::size_type std::map<_Key, _Tp, _Compare, _Alloc>::count(const key_type&) const [with _Key = std::pair<int, int>; _Tp = int; _Compare = compare_keys; _Alloc = std::allocator<std::pair<const std::pair<int, int>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::size_type = long unsigned int; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::pair<int, int>]’
Matrix.hh:23:9: required from ‘bool Matrix<T>::emplace(int, int, T) [with T = int]’
main.cpp:7:5: required from here
/usr/include/c++/9/bits/stl_tree.h:1945:6: error: no match for call to ‘(const compare_keys) (const std::pair<int, int>&, const std::pair<int, int>&)’
1945 | if (!_M_impl._M_key_compare(_S_key(__x), __k))
In file included from main.cpp:3:
Matrix.hh:6:10: note: candidate: ‘bool compare_keys::operator()(const key&, const key&)’ <near match>
6 | bool operator() (const key& left_key, const key& right_key) {
| ^~~~~~~~
Matrix.hh:6:10: note: passing ‘const compare_keys*’ as ‘this’ argument discards qualifiers
The Matrix class:
#include <map>
#include <iostream>
typedef std::pair<int,int> key;
struct compare_keys {
bool operator() (const key& left_key, const key& right_key) {
if (left_key.first < right_key.first) return true;
if (left_key.first > right_key.first) return false;
return left_key.second > right_key.second;
}
};
template <typename T>
class Matrix {
private:
//Sparse matrix representation
std::map<key, T, compare_keys> values;
int max_row, max_col;
public:
Matrix() : max_row(0), max_col(0) {};
Matrix(int rows, int cols) : max_row(rows), max_col(cols) {};
bool emplace(int row, int col, T value) {
if (this->values.count(std::make_pair(row, col)))
return false;
this->values[std::make_pair(row, col)] = value;
if (row > max_row) max_row = row;
if (col > max_col) max_col = col;
return true;
}
};
I don't see why the compare_keys operator doesn't match the comparator in the map constructor.
You are missing const.
bool operator() (const key& left_key, const key& right_key) const {
^^^^^

What are all these errors about?

I hate copypasting the whole log here but I can't understand what these errors mean...
I understand some of them have to do with the way I'm using the unique_ptr, but since my IDE doesn't directly point out the incriminated lines I don't know what to do.
In file included from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/i686-w64-mingw32/bits/c++allocator.h:33,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/allocator.h:46,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/string:41,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/locale_classes.h:40,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/ios_base.h:41,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/ios:42,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/ostream:38,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/iostream:39,
from C:\Users\Andrea\CLionProjects\Final_Project_2nd\Column.h:8,
from C:\Users\Andrea\CLionProjects\Final_Project_2nd\Tab.h:8,
from C:\Users\Andrea\CLionProjects\Final_Project_2nd\Tab.cpp:5:
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/ext/new_allocator.h: In instantiation of 'void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> >; _Args = {const std::pair<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<Column, std::default_delete<Column> > >&}; _Tp = std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >]':
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/alloc_traits.h:475:4: required from 'static void std::allocator_traits<std::allocator<_CharT> >::construct(std::allocator_traits<std::allocator<_CharT> >::allocator_type&, _Up*, _Args&& ...) [with _Up = std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> >; _Args = {const std::pair<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<Column, std::default_delete<Column> > >&}; _Tp = std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >; std::allocator_traits<std::allocator<_CharT> >::allocator_type = std::allocator<std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > > >]'
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/stl_tree.h:637:32: required from 'void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_construct_node(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type, _Args&& ...) [with _Args = {const std::pair<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<Column, std::default_delete<Column> > >&}; _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> >; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >*]'
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/stl_tree.h:506:3: required from 'std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Reuse_or_alloc_node::operator()(_Arg&&) [with _Arg = const std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> >&; _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> >; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >*]'
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/stl_tree.h:677:33: required from 'std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_clone_node(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Const_Link_type, _NodeGen&) [with _NodeGen = std::_Rb_tree<std::__cxx11::basic_string<char>, std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> >, std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > > >::_Reuse_or_alloc_node; _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> >; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >*; 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::unique_ptr<Column> > >*]'
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/stl_tree.h:1834:13: required from 'std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_copy(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Const_Link_type, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr, _NodeGen&) [with _NodeGen = std::_Rb_tree<std::__cxx11::basic_string<char>, std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> >, std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > > >::_Reuse_or_alloc_node; _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> >; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >*; 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::unique_ptr<Column> > >*; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr = std::_Rb_tree_node_base*]'
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/stl_tree.h:891:15: required from 'std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_copy(const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&, _NodeGen&) [with _NodeGen = std::_Rb_tree<std::__cxx11::basic_string<char>, std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> >, std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > > >::_Reuse_or_alloc_node; _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> >; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >*]'
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/stl_tree.h:1742:16: required from 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::operator=(const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&) [with _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> >; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >]'
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/stl_map.h:100:11: required from here
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/ext/new_allocator.h:136:4: error: use of deleted function 'constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = const std::__cxx11::basic_string<char>; _T2 = std::unique_ptr<Column>]'
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/stl_algobase.h:64,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/char_traits.h:39,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/ios:40,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/ostream:38,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/iostream:39,
from C:\Users\Andrea\CLionProjects\Final_Project_2nd\Column.h:8,
from C:\Users\Andrea\CLionProjects\Final_Project_2nd\Tab.h:8,
from C:\Users\Andrea\CLionProjects\Final_Project_2nd\Tab.cpp:5:
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/stl_pair.h:292:17: note: 'constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = const std::__cxx11::basic_string<char>; _T2 = std::unique_ptr<Column>]' is implicitly deleted because the default definition would be ill-formed:
constexpr pair(const pair&) = default;
^~~~
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/stl_pair.h:292:17: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Column; _Dp = std::default_delete<Column>]'
In file included from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/locale_conv.h:41,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/locale:43,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/iomanip:43,
from C:\Users\Andrea\CLionProjects\Final_Project_2nd\Date.h:12,
from C:\Users\Andrea\CLionProjects\Final_Project_2nd\DateColumn.h:8,
from C:\Users\Andrea\CLionProjects\Final_Project_2nd\Tab.h:14,
from C:\Users\Andrea\CLionProjects\Final_Project_2nd\Tab.cpp:5:
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/unique_ptr.h:394:7: note: declared here
unique_ptr(const unique_ptr&) = delete;
^~~~~~~~~~
mingw32-make.exe[3]: *** [CMakeFiles\Final_Project_2nd.dir\build.make:179: CMakeFiles/Final_Project_2nd.dir/Tab.cpp.obj] Error 1
mingw32-make.exe[3]: *** Waiting for unfinished jobs....
mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:75: CMakeFiles/Final_Project_2nd.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:82: CMakeFiles/Final_Project_2nd.dir/rule] Error 2
mingw32-make.exe: *** [Makefile:117: Final_Project_2nd] Error 2
This is Tab.h:
class Tab {
public:
Tab();
~Tab();
void addColumn(string name, string type);
void addRecord(string column);
void operator=(const Tab& to_assign);
private:
map<string, unique_ptr<Column>> _columns;
int _primary_key;
};
And these are two methods:
void Tab::addColumn(string name, string type) {
// I switch all the different types and create a new element on the columns map
// depending on what is the result
switch(Type2Int(type)) {
case OptionInt:
_columns[name].reset(new IntColumn());
break;
case OptionFloat:
_columns[name].reset(new FloatColumn());
break;
case OptionChar:
_columns[name].reset(new CharColumn());
break;
case OptionText:
_columns[name].reset(new TextColumn());
break;
case OptionTime:
_columns[name].reset(new TimeColumn());
break;
case OptionDate:
_columns[name].reset(new DateColumn());
break;
}
}
void Tab::operator=(const Tab &to_assign) {
_columns = to_assign._columns;
}
ColumnImpl class:
template <typename T> class ColumnImpl : public Column {
public:
ColumnImpl();
ColumnImpl(const T& to_set);
vector<T> const& getData() const { return _data; }
void addElem(const T& elem_to_add);
void operator=(const ColumnImpl& to_assign);
protected:
vector<T> _data;
};
And this is a supsect method:
template<typename T>
void ColumnImpl<T>::operator=(const ColumnImpl &to_assign) {
_data = to_assign._data;
}
Database.h:
class Database {
public:
Database();
~Database();
void createNewTable(string name);
void addColumnToTab(string tab_name, string col_name, string type);
private:
map<string, Tab> _tables;
};
These are the only two methods I've implemented:
void Database::createNewTable(string name) {
_tables[name] = Tab();
}
void Database::addColumnToTab(string tab_name, string col_name, string type) {
const auto & it_target_tab = _tables.find(tab_name);
it_target_tab->second.addColumn(col_name, type);
}

std::map both costume compare functor and function/ lambda error

I have the following:
inputs:
Map1["Ram"] = 8;
Map1["Aam"] = 8;
Map1["Some"] = 2;
Map1["He"] = 5;
Map1["He"] = 6;
The expected output after insertion to the std::map<std::string, int> should be:
Output:
"Some" 2
"He" 5
"He" 6
"Aam" 8
Please note that:
sorting is according to the values, not keys.
the input Map1["Ram"] = 8; has overwritten by the next input Map1["Aam"] = 8;
Approach 1: Using a functor I was thinking to manage it. I have got this two errors:
||=== Build: Debug in MyTestProgram (compiler: GNU GCC Compiler) ===|
d:\mingw\include\c++\7.3.0\bits\stl_map.h||In instantiation of 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](std::map<_Key, _Tp, _Compare, _Alloc>::key_type&&) [with _Key = std::__cxx11::basic_string<char>; _Tp = int; _Compare = compare_functor; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = int; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::__cxx11::basic_string<char>]':|
D:\Programming\C++\CPP Programs\MyTestProgram\MyTestProgram.cpp|22|required from here|
d:\mingw\include\c++\7.3.0\bits\stl_map.h|511|error: no match for call to '(std::map<std::__cxx11::basic_string<char>, int, compare_functor>::key_compare {aka compare_functor}) (std::map<std::__cxx11::basic_string<char>, int, compare_functor>::key_type&, const std::__cxx11::basic_string<char>&)'|
D:\Programming\C++\CPP Programs\MyTestProgram\MyTestProgram.cpp|12|note: candidate: bool compare_functor::operator()(const T&, const T&) const|
D:\Programming\C++\CPP Programs\MyTestProgram\MyTestProgram.cpp|12|note: no known conversion for argument 1 from 'std::map<std::__cxx11::basic_string<char>, int, compare_functor>::key_type {aka std::__cxx11::basic_string<char>}' to 'const T& {aka const std::pair<std::__cxx11::basic_string<char>, int>&}'|
d:\mingw\include\c++\7.3.0\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_lower_bound(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr, const _Key&) [with _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, int>; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, int> >; |
d:\mingw\include\c++\7.3.0\bits\stl_tree.h|1187|required from 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::lower_bound(const key_type&) [with _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, int>; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, int> >; _Compare = compare_functor; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> >; std::_Rb_tree<_Key, _Val, _KeyOfVa|
d:\mingw\include\c++\7.3.0\bits\stl_map.h|1234|required from 'std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::lower_bound(const key_type&) [with _Key = std::__cxx11::basic_string<char>; _Tp = int; _Compare = compare_functor; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::__cxx11::basic_string<char>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::__cxx11::basic_string<char|
d:\mingw\include\c++\7.3.0\bits\stl_map.h|509|required from 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](std::map<_Key, _Tp, _Compare, _Alloc>::key_type&&) [with _Key = std::__cxx11::basic_string<char>; _Tp = int; _Compare = compare_functor; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = int; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::__cxx11::basic_string<char>]'|
Program.cpp|22|required from here|
d:\mingw\include\c++\7.3.0\bits\stl_tree.h|1872|error: no match for call to '(compare_functor) (const std::__cxx11::basic_string<char>&, const std::__cxx11::basic_string<char>&)'|
Program.cpp|12|note: candidate: bool compare_functor::operator()(const T&, const T&) const|
Program.cpp|12|note: no known conversion for argument 1 from 'const std::__cxx11::basic_string<char>' to 'const T& {aka const std::pair<std::__cxx11::basic_string<char>, int>&}'|
||=== Build failed: 2 error(s), 7 warning(s) (0 minute(s), 0 second(s)) ===|
Approach 2: The same logic I implemented with a lambda and I have got almost the same errors:
||=== Build: Debug in MyTestProgram (compiler: GNU GCC Compiler) ===|
d:\mingw\include\c++\7.3.0\bits\stl_map.h||In instantiation of 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](std::map<_Key, _Tp, _Compare, _Alloc>::key_type&&) [with _Key = std::__cxx11::basic_string<char>; _Tp = int; _Compare = bool (*)(const std::pair<std::__cxx11::basic_string<char>, int>&, const std::pair<std::__cxx11::basic_string<char>, int>&); _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = int; std:|
Program.cpp|37|required from here|
d:\mingw\include\c++\7.3.0\bits\stl_map.h|511|error: invalid initialization of reference of type 'const std::pair<std::__cxx11::basic_string<char>, int>&' from expression of type 'std::map<std::__cxx11::basic_string<char>, int, bool (*)(const std::pair<std::__cxx11::basic_string<char>, int>&, const std::pair<std::__cxx11::basic_string<char>, int>&)>::key_type {aka std::__cxx11::basic_string<char>}'|
d:\mingw\include\c++\7.3.0\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_lower_bound(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr, const _Key&) [with _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, int>; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, int> >; |
d:\mingw\include\c++\7.3.0\bits\stl_tree.h|1187|required from 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::lower_bound(const key_type&) [with _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, int>; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, int> >; _Compare = bool (*)(const std::pair<std::__cxx11::basic_string<char>, int>&, const std::pair<std::__cxx11::basic_string<char>, int>&); _Alloc = |
d:\mingw\include\c++\7.3.0\bits\stl_map.h|1234|required from 'std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::lower_bound(const key_type&) [with _Key = std::__cxx11::basic_string<char>; _Tp = int; _Compare = bool (*)(const std::pair<std::__cxx11::basic_string<char>, int>&, const std::pair<std::__cxx11::basic_string<char>, int>&); _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::__cxx11::ba|
d:\mingw\include\c++\7.3.0\bits\stl_map.h|509|required from 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](std::map<_Key, _Tp, _Compare, _Alloc>::key_type&&) [with _Key = std::__cxx11::basic_string<char>; _Tp = int; _Compare = bool (*)(const std::pair<std::__cxx11::basic_string<char>, int>&, const std::pair<std::__cxx11::basic_string<char>, int>&); _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = int; std::map<_|
Program.cpp|37|required from here|
d:\mingw\include\c++\7.3.0\bits\stl_tree.h|1872|error: invalid initialization of reference of type 'const std::pair<std::__cxx11::basic_string<char>, int>&' from expression of type 'const std::__cxx11::basic_string<char>'|
||=== Build failed: 2 error(s), 7 warning(s) (0 minute(s), 0 second(s)) ===|
I have referred many answers online. But most of them were considering either Key type or Value type while comparing using the functor/ lambda, which was not my case. I would like to compare both Value and Key compared while inserting to the map.
Can anybody explain to me why these implementations fail?
Secondly, what I should have done to get above result while inserting(PS: I would like to still keep string as my key to the map and if it is possible, I do not want any temporary maps to do this result.)?
Here is my code:
#include <iostream>
#include <map>
#include <string>
#include <tuple>
typedef std::pair<std::string, int> T;
typedef bool(*compare_functional_type)(const T&, const T&);
// Way - 1: using functor
struct compare_functor
{
bool operator()(const T& A ,const T& B)const
{
return std::tie(A.second, A.first) < std::tie(B.second, B.first);
// OR in other-words:
//return (A.second == B.second) ? A.first < B.first : A.second < B.second;
};
};
int main()
{
std::map<std::string, int, compare_functor> Map1;
Map1["Ram"] = 8;
Map1["Aam"] = 8;
Map1["Some"] = 2;
Map1["He"] = 5;
Map1["He"] = 6;
// Way - 2: using lambdas and function pointers
compare_functional_type Lambda = [](const T& A, const T& B)
{
return std::tie(A.second, A.first) < std::tie(B.second, B.first);
// OR in other-words:
//return (A.second == B.second) ? A.first < B.first : A.second < B.second;
};
std::map<std::string, int, compare_functional_type> Map2(Lambda);
Map2["Ram"] = 8;
Map2["Aam"] = 8;
Map2["Some"] = 2;
Map2["He"] = 5;
Map2["He"] = 6;
return 0;
}
std::map<int, std::string> is what you want.
To have your inverted syntax, you might use wrapper, something like:
class Wrapper
{
public:
Wrapper(std::map<int, std::string>& m, const std::string& s) : m(m), s(s) {}
void operator =(int k) { m[k] = s; }
private:
std::map<int, std::string>& m;
std::string s;
};
class InvertedMap
{
public:
Wrapper operator[](const std::string& s) { return {m, s}; }
auto begin() const { return m.begin(); }
auto end() const { return m.end(); }
private:
std::map<int, std::string> m;
};
And then:
InvertedMap Map1;
Map1["Ram"] = 8;
Map1["Aam"] = 8;
Map1["Some"] = 2;
Map1["He"] = 5;
Map1["He"] = 6;
for (const auto& p : Map1) {
std::cout << p.second << " " << p.first << std::endl;
}
// Output:
// Some 2
// He 5
// He 6
// Aam 8
Demo

c++11, why does this unordered_map defined for vector <int> not work?

I am trying to create an unordered_map<vector<int>, int>. I know that I need to have my own hash function, so I tried to build one. I am capable of creating it and compiling it fine, but I get compilation errors when I try to access it.
Here is the code:
#include <bits/stdc++.h>
using namespace std;
class mhash {
public:
std::size_t operator()(std::vector<int> const& vec) const {
std::size_t seed = vec.size();
for(auto& i : vec) {
seed ^= i + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
return seed;
}
};
map <vector <int>,int, mhash> M;
int main(){
vector <int> V;
M[V]=5;
cout << M[V];
}
I am compiling using g++ -std=c++11.
If I only declare the unordered_map it compiles fine, but when I try to use it I get the following errors:
In file included from /usr/include/c++/5/map:61:0,
from /usr/include/x86_64-linux-gnu/c++/5/bits/stdc++.h:80,
from exp.cpp:1:
/usr/include/c++/5/bits/stl_map.h: In instantiation of ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = std::vector<int>; _Tp = int; _Compare = mhash; _Alloc = std::allocator<std::pair<const std::vector<int>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = int; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::vector<int>]’:
exp.cpp:19:5: required from here
/usr/include/c++/5/bits/stl_map.h:481:32: error: no match for call to ‘(std::map<std::vector<int>, int, mhash>::key_compare {aka mhash}) (const key_type&, const std::vector<int>&)’
if (__i == end() || key_comp()(__k, (*__i).first))
^
exp.cpp:6:15: note: candidate: std::size_t mhash::operator()(const std::vector<int>&) const
std::size_t operator()(std::vector<int> const& vec) const {
^
exp.cpp:6:15: note: candidate expects 1 argument, 2 provided
In file included from /usr/include/c++/5/map:60:0,
from /usr/include/x86_64-linux-gnu/c++/5/bits/stdc++.h:80,
from exp.cpp:1:
/usr/include/c++/5/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_lower_bound(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type, const _Key&) [with _Key = std::vector<int>; _Val = std::pair<const std::vector<int>, int>; _KeyOfValue = std::_Select1st<std::pair<const std::vector<int>, int> >; _Compare = mhash; _Alloc = std::allocator<std::pair<const std::vector<int>, int> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::vector<int>, int> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const std::vector<int>, int> >*]’:
/usr/include/c++/5/bits/stl_tree.h:1091:30: required from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::lower_bound(const key_type&) [with _Key = std::vector<int>; _Val = std::pair<const std::vector<int>, int>; _KeyOfValue = std::_Select1st<std::pair<const std::vector<int>, int> >; _Compare = mhash; _Alloc = std::allocator<std::pair<const std::vector<int>, int> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::vector<int>, int> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::key_type = std::vector<int>]’
/usr/include/c++/5/bits/stl_map.h:916:36: required from ‘std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::lower_bound(const key_type&) [with _Key = std::vector<int>; _Tp = int; _Compare = mhash; _Alloc = std::allocator<std::pair<const std::vector<int>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::vector<int>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::vector<int>]’
/usr/include/c++/5/bits/stl_map.h:479:28: required from ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = std::vector<int>; _Tp = int; _Compare = mhash; _Alloc = std::allocator<std::pair<const std::vector<int>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = int; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::vector<int>]’
exp.cpp:19:5: required from here
/usr/include/c++/5/bits/stl_tree.h:1628:6: error: no match for call to ‘(mhash) (const std::vector<int>&, const std::vector<int>&)’
if (!_M_impl._M_key_compare(_S_key(__x), __k))
^
exp.cpp:6:15: note: candidate: std::size_t mhash::operator()(const std::vector<int>&) const
std::size_t operator()(std::vector<int> const& vec) const {
^
exp.cpp:6:15: note: candidate expects 1 argument, 2 provided
You wrote map, not unordered_map.
But... if you want a map:
The third template argument for a map is not a hash, but a comparator.
bool operator()(a, b)
Because you instantiated a std::map, not an std::unordered_map.
Normal maps don't take hash functions.
Presumably this is just a typo.
By the way, avoid #include <bits/stdc++.h>.

What's wrong with this moveable type for std::map?

I want to put a moveable but not copyable type as a value in std::map. Here is some simple code to test the principle.
#include <map>
struct Foo
{
Foo ();
Foo (const Foo &) = delete;
Foo & operator = (const Foo &) = delete;
Foo (Foo &&) {}
Foo & operator = (Foo &&) {return *this;}
};
int main ()
{
std :: map <int, Foo> m;
m .insert (std :: make_pair (123, Foo ()));
}
I compile this with g++ test.cpp --std=c++0x (gcc version 4.5.1 on Ubuntu 12.04). There is a big ugly error as shown below. What is the problem?
In file included from /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_algobase.h:66:0,
from /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_tree.h:62,
from /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/map:60,
from test.cpp:1: test.cpp: In copy constructor ‘std::pair<const int, Foo>::pair(const std::pair<const int, Foo>&)’: /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_pair.h:72:5: instantiated from ‘std::_Rb_tree_node<_Val>::_Rb_tree_node(_Args&& ...) [with _Args = {const std::pair<const int, Foo>&}, _Val = std::pair<const int, Foo>]’ /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/ext/new_allocator.h:111:4: instantiated from ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Tp*,
_Args&& ...) [with _Args = {const std::pair<const int, Foo>&}, _Tp = std::_Rb_tree_node<std::pair<const int, Foo> >, _Tp* = std::_Rb_tree_node<std::pair<const int, Foo> >*]’ /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_tree.h:394:8: instantiated from ‘std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val,
_KeyOfValue, _Compare, _Alloc>::_M_create_node(_Args&& ...) [with _Args = {const std::pair<const int, Foo>&}, _Key = int, _Val = std::pair<const int, Foo>, _KeyOfValue = std::_Select1st<std::pair<const int, Foo> >, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, Foo> >, std::_Rb_tree_node<_Val>* = std::_Rb_tree_node<std::pair<const int, Foo> >*]’ /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_tree.h:899:42: instantiated from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare,
_Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_(const std::_Rb_tree_node_base*, const std::_Rb_tree_node_base*, const _Val&) [with _Key = int, _Val = std::pair<const int, Foo>, _KeyOfValue = std::_Select1st<std::pair<const int, Foo> >, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, Foo> >, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const int, Foo> >, const std::_Rb_tree_node_base* = const std::_Rb_tree_node_base*]’ /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_tree.h:1191:65: instantiated from ‘std::pair<std::_Rb_tree_iterator<_Val>, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare,
_Alloc>::_M_insert_unique(const _Val&) [with _Key = int, _Val = std::pair<const int, Foo>, _KeyOfValue = std::_Select1st<std::pair<const int, Foo> >, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, Foo> >]’ /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_map.h:501:41: instantiated from ‘std::pair<typename std::map<_Key, _Tp, _Compare,
_Alloc>::_Rep_type::iterator, bool> std::map<_Key, _Tp, _Compare, _Alloc>::insert(const std::map<_Key, _Tp, _Compare, _Alloc>::value_type&) [with _Key = int, _Tp = Foo, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, Foo> >, typename std::map<_Key, _Tp, _Compare, _Alloc>::_Rep_type::iterator = std::_Rb_tree_iterator<std::pair<const int, Foo> >, std::map<_Key,
_Tp, _Compare, _Alloc>::value_type = std::pair<const int, Foo>]’ test.cpp:20:43: instantiated from here test.cpp:7:2: error: deleted function ‘Foo::Foo(const Foo&)’ /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_pair.h:72:5: error: used here In file included from /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/map:60:0,
from test.cpp:1: /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_tree.h: In constructor ‘std::_Rb_tree_node<_Val>::_Rb_tree_node(_Args&& ...) [with _Args = {const std::pair<const int, Foo>&}, _Val = std::pair<const int, Foo>]’: /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_tree.h:136:49: note: synthesized method ‘std::pair<const int, Foo>::pair(const std::pair<const int, Foo>&)’ first required here
I'm adding some details for future references: this bug as Quux pointed out was caused in gcc 4.5.1 by a problem in the move constructor for std::pair.
As of today the issue has been fixed and you should either upgrade your compiler version or workaround by using another version of the standard library.
Your code works just fine