2016-04-12 4 views
0

Ich versuche ein unordered_map für <xml_node*,string> Paar zu erstellen, wobei xml_node ein Element von XML aus pugixml Bibliothek ist, und ich möchte seinen Zeiger als Schlüssel speichern. Ich habe die Karte wie folgt erklärt:unordered_map für <Zeiger, String> in C++

unordered_map<xml_node*,string> label_hash; 

Nun ist die insert Funktion funktioniert gut und gut. Aber wenn ich versuche zu find ein Element aus dem Hash wie folgt aus:

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

bekomme ich folgende Fehlermeldung:

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)’| 

Jetzt muss ich eine Hash-Funktion und gleiche Funktion für die Karte implementieren? Ich habe versucht, sie wie folgt zu implementieren, aber es funktioniert nicht:

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); 
    } 
}; 

Ich bin ein bisschen neu in C++ so ein wenig Hilfe wäre toll!

Antwort

5

Bitte lesen Sie die Dokumentation: unordered_map::find gibt einen Iterator an pair<xml_node const*, string> zurück. (Sie können nicht, dass an den string Konstruktor übergeben.) Statt dies tun:

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 
} 
+0

danke! hat perfekt funktioniert! eine weitere Frage, wie man testet, ob der Schlüssel (Zeiger hier) im Hash vorhanden ist oder nicht? Ich versuchte einen Zeiger, der nicht im Hash ist und zu einem Seg Fehler führte –

+0

@ KoustuvSinha Überprüfen Sie die Änderung. – emlai

+0

vielen Dank @zenith :) –

1

ich ein kleines Testprogramm geschrieben:

#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; 

} 

Die perfekt kompiliert, was darauf hinweist, dass wie vermutet wird, das Problem ist nicht mit der Verwendung eines Zeigers als Kartenschlüssel, nicht ein Mangel an benutzerdefinierten Vergleich und nicht das Fehlen einer Hash-Funktion.

unordered_map :: find gibt einen Iterator zurück, der auf ein Schlüssel/Wert-Paar zeigt.

+0

danke! also gibt i-> zuerst den Schlüssel und i-> zweiten gibt den Wert richtig? –

+0

@ KoustuvSinha absolut richtig. –