简体   繁体   中英

unordered_map for <Pointer, String> in C++

I am trying to create an unordered_map for <xml_node*,string> pair, where xml_node is an element of xml from pugixml library, and i wish to store its pointer as the key. I have declared the map like this :

unordered_map<xml_node*,string> label_hash;

Now the insert function is working well and good. But whenever I try to find an element from the hash like this :

string lb = string(label_hash.find(node));

I get the following error :

no matching function for call to ‘std::basic_string<char>::basic_string(std::_Hashtable<pugi::xml_node*, std::pair<pugi::xml_node* const, std::basic_string<char> >, std::allocator<std::pair<pugi::xml_node* const, std::basic_string<char> > >, std::_Select1st<std::pair<pugi::xml_node* const, std::basic_string<char> > >, std::equal_to<pugi::xml_node*>, std::hash<pugi::xml_node*>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, false, false, true>::iterator)’|

Now do I need to implement a hash function and equal function for the map? I was trying to implement them like follows but it doesn't work :

struct hashing_func {
    unsigned long operator()(const xml_node* key) const {
        uintptr_t ad = (uintptr_t)key;
        return (size_t)((13 * ad) ^ (ad >> 15));
        //return hash<xml_node*>(key);
    }
};

struct key_equal_fn {
    bool operator()(const xml_node* t1, const xml_node* t2) const {
        return (t1 == t2);
    }
};

I am a bit new to C++ so a little help would be great!

Please read the documentation: unordered_map::find returns an iterator to pair<xml_node const*, string> . (You can't pass that to the string constructor.) Instead do this:

auto iterator = label_hash.find(node);

if (iterator != label_hash.end()) { // `.find()` returns `.end()` if the key is not in the map
    string& lb = iterator->second; // The `&` is optional here, use it if you don't want to deepcopy the whole string.
    // use lb
}
else {
    // key not in the map
}

I wrote a little test program:

#include <unordered_map>
#include <string>
namespace pugi
{ 
  struct xml_node {};
}

int main()
{
  std::unordered_map<pugi::xml_node*, std::string> mymap;

  pugi::xml_node n1;

  mymap.emplace(&n1, "foo");

  auto i = mymap.find(&n1);

  i->second;

  return 0;

}

This compiles perfectly, indicating that as, suspected, the problem is not with the use of a pointer as a map key, not a lack of custom comparitor and not the lack of a hash function.

unordered_map::find returns an iterator - which points to a key/value pair.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM