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>
^
CodePudding user response:
In order to be used as a key in an unordered container, the key class must meet two requirements:
The key must have an equality operator defined
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.