1

In java, I can create a Map of a Map as following:

Map<Map<String, Integer>, List<String>> m = new HashMap<>();

Can I and if yes, How can I do similar in C++?

I tried doing

   unordered_map<unordered_map<char, int>, vector<string>> m;

and I am getting compilation error as:

Line 4: Char 65: error: call to implicitly-deleted default constructor of 'unordered_map<unordered_map<char, int>, vector<std::string>>' (aka 'unordered_map<unordered_map<char, int>, vector<basic_string<char>>>')
        unordered_map<unordered_map<char, int>, vector<string>> m;
                                                                ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/unordered_map.h:141:7: note: explicitly defaulted function was implicitly deleted here
      unordered_map() = default;
      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/unordered_map.h:105:18: note: default constructor of 'unordered_map<std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int>>>, std::vector<std::__cxx11::basic_string<char>, std::allocator<std::__cxx11::basic_string<char>>>, std::hash<std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int>>>>, std::equal_to<std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int>>>>, std::allocator<std::pair<const std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int>>>, std::vector<std::__cxx11::basic_string<char>, std::allocator<std::__cxx11::basic_string<char>>>>>>' is implicitly deleted because field '_M_h' has a deleted default constructor
      _Hashtable _M_h;
                 ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable.h:414:7: note: explicitly defaulted function was implicitly deleted here
      _Hashtable() = default;
      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable.h:174:7: note: default constructor of '_Hashtable<std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int>>>, std::pair<const std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int>>>, std::vector<std::__cxx11::basic_string<char>, std::allocator<std::__cxx11::basic_string<char>>>>, std::allocator<std::pair<const std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int>>>, std::vector<std::__cxx11::basic_string<char>, std::allocator<std::__cxx11::basic_string<char>>>>>, std::__detail::_Select1st, std::equal_to<std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int>>>>, std::hash<std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int>>>>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true>>' is implicitly deleted because base class '__detail::_Hashtable_base<unordered_map<char, int, hash<char>, equal_to<char>, allocator<pair<const char, int>>>, pair<const unordered_map<char, int, hash<char>, equal_to<char>, allocator<pair<const char, int>>>, vector<basic_string<char>, allocator<basic_string<char>>>>, _Select1st, equal_to<unordered_map<char, int, hash<char>, equal_to<char>, allocator<pair<const char, int>>>>, hash<unordered_map<char, int, hash<char>, equal_to<char>, allocator<pair<const char, int>>>>, _Mod_range_hashing, _Default_ranged_hash, _Hashtable_traits<true, false, true>>' has a deleted default constructor
    : public __detail::_Hashtable_base<_Key, _Value, _ExtractKey, _Equal,
      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable_policy.h:1822:5: note: explicitly defaulted function was implicitly deleted here
    _Hashtable_base() = default;
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable_policy.h:1771:5: note: default constructor of '_Hashtable_base<std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int>>>, std::pair<const std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int>>>, std::vector<std::__cxx11::basic_string<char>, std::allocator<std::__cxx11::basic_string<char>>>>, std::__detail::_Select1st, std::equal_to<std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int>>>>, std::hash<std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int>>>>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Hashtable_traits<true, false, true>>' is implicitly deleted because base class '_Hash_code_base<std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int>>>, std::pair<const std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int>>>, std::vector<std::__cxx11::basic_string<char>, std::allocator<std::__cxx11::basic_string<char>>>>, std::__detail::_Select1st, std::hash<std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int>>>>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, _Hashtable_traits<true, false, true>::__hash_cached::value>' has a deleted default constructor
  : public _Hash_code_base<_Key, _Value, _ExtractKey, _H1, _H2, _Hash,
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable_policy.h:1373:7: note: explicitly defaulted function was implicitly deleted here
      _Hash_code_base() = default;
      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable_policy.h:1349:7: note: default constructor of '_Hash_code_base<std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int>>>, std::pair<const std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int>>>, std::vector<std::__cxx11::basic_string<char>, std::allocator<std::__cxx11::basic_string<char>>>>, std::__detail::_Select1st, std::hash<std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int>>>>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, true>' is implicitly deleted because base class '_Hashtable_ebo_helper<1, std::hash<std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int>>>>>' has a deleted default constructor
      private _Hashtable_ebo_helper<1, _H1>,
      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable_policy.h:1096:7: note: explicitly defaulted function was implicitly deleted here
      _Hashtable_ebo_helper() = default;
      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/hashtable_policy.h:1094:7: note: default constructor of '_Hashtable_ebo_helper<1, std::hash<std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int>>>>, true>' is implicitly deleted because base class 'std::hash<std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int>>>>' has a deleted default constructor
    : private _Tp
      ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/functional_hash.h:101:19: note: default constructor of 'hash<std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int>>>>' is implicitly deleted because base class '__hash_enum<std::unordered_map<char, int, std::hash<char>, std::equal_to<char>, std::allocator<std::pair<const char, int>>>>' has no default constructor
    struct hash : __hash_enum<_Tp>
                  ^
CodeTalker
  • 1,683
  • 2
  • 21
  • 31
  • You would need to provide your own hashing function for `std::unordered_map`. And I'm not sure how do you expect to access elements of this map by key (are you going to build maps on th fly each time you want to access a vector? Use a lookup table to get pre-built maps?) – Yksisarvinen Jul 17 '22 at 18:52
  • Does this answer your question? [Call to implicitly-deleted default constructor of 'unordered\_set< vector >'](https://stackoverflow.com/questions/62869571/call-to-implicitly-deleted-default-constructor-of-unordered-set-vectorint) – liorko Jul 17 '22 at 18:55
  • Yes @Yksisarvinen the idea is to build map on the fly and check it's existence in my bigger map. – CodeTalker Jul 17 '22 at 19:22

1 Answers1

3

In order to be used as a key in an unordered container, the key class must meet two requirements:

  1. The key must have an equality operator defined

  2. The key must have a hash function defined.

Unordered maps, themselves, have a default == overload, which satisfies the first requirement.

However, unordered maps do not have a default hash function, and this is why you can't create your unordered map.

It is possible, by using advanced C++ topics and concepts, to implement and specify an appropriate hash function for your unordered map. Your C++ textbook that covers advanced C++ topics should have an explanation and some examples.

However it is probably simpler for you to use to switch to a std::map, which will be sufficient for simple use cases. The key requirements for ordered containers are slightly different: mostly a < overload, which std::map has a default implementation of.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148