boost::hash, schönere variante?



  • Hi,

    ich möchte gerne in meinen klassen eine "get_hash ()"-methode einbauen und dafür boost benutzen, doch nicht jedes mal wenn ich den hash haben will einen boost::hash erzeugen muss.

    Ich hab es so derzeit gemacht, doch diese lösung gefällt mir nicht (2. hash_value-methode)

    #include <boost/functional/hash.hpp>
    #include <cassert>
    #include <iostream>
    #include <string>
    
    class point
    {
        int x;
        int y;
    public:
        point() : x(0), y(0) {}
        point(int x, int y) : x(x), y(y) {}
    
        bool operator==(point const& other) const
        {
            return x == other.x && y == other.y;
        }
    
        friend std::size_t hash_value(point const& p)
        {
            std::wstring value = L"hallo welt ";
            std::size_t seed = 0;
            boost::hash_combine(seed, p.x);
            boost::hash_combine(seed, p.y);
            boost::hash_combine(seed, value);
    
            return seed;
        }
    
        std::size_t hash_value (void) const
        {
            boost::hash<point> hasher;
            return (hasher (*this));
        }
    };
    
    int main()
    {
        point p1(0, 0);
    
        std::cout << p1.hash_value () << std::endl;
    
        return 0;
    }
    

    Jemand eine bessere idee, oder kann ich den hash nur bekommen, wenn ich einen "hasher" benutze?

    Viele Grüße!
    Booster



  • Wo liegt denn dein Problem?
    Benutz' einfach Boost.Hash wie es gemacht ist und es funktioniert alles wie es soll ;).

    Wofür braucht dein Objekt denn überhaupt eine Methode, die seinen Hash zurückgibt? Sieht mir nicht nach so tollem Design aus…



  • ah, du findest es also "eleganter" jedesmal wenn ich einen hash erfrage immer ein objekt von boost::hash<T> anzulegen? selbst wenn ich in einer methode von 10 verschiedenen objekten die hashs brauche und dafür 10 von den hash-dingern anlegen muss? also wenn du das "schöner" findest, ich hab da lieber einfach ein objekt.hash_value (); und hab ruhe und platz gespart.



  • booster schrieb:

    ah, du findest es also "eleganter" jedesmal wenn ich einen hash erfrage immer ein objekt von boost::hash<T> anzulegen?...

    Also ich weiß nicht, was daran komisch klingen soll.
    "Einen Hash erfragen" und "einen hash anlegen" sind doch genau die beiden Sichtweisen des von Dir geforderten Vorgangs.
    Genauso wie "einen Namensstring erfragen" und "einen Namensstring anlegen"....
    ... und mit "Performance" würde ich nie argumentieren ohne konkrete Messungen.

    Hast Du eigentlich Erfahrungen mit "Funktoren"/"Funktionsobjekten" ?
    Das sind zwar semantisch betrachtet Objekte, im Compilat sind es aber einfach Funktionen, die aufgerufen werden. Ergo: "Objekt anlegen" muss sich performancetechnisch nicht anders verhalten als "Funktion aufrufen".

    Gruß,

    Simon2.



  • what the hell are you talking about?
    ich versteh nur bahnhof



  • Ist auch wurscht, wenn du 10 Hashes haben willst wirst du aber sicherlich nicht 10 Objekte anlegen. boost::hash ist ein Funktionsobjekt, du legst also quasi damit eine Funktion an:

    boost::hash<point> hasher;
    
    std::vector<std::size_t> da_hashes;
    for (std::vector<point>::const_iterator i = v.begin(); i != v.end(); ++i)
        da_hashes.push_back(hasher(*i));
    

    An dem Beispiel kannst du auch sehr schön sehen, warum das Objekt sinnvoll sein könnte, damit kannst du nämlich richtig toll STL machen:

    // Initialisierung wie oben, aber:
    std::transform(v.begin(), v.end(), std::back_inserter(da_hashes), hasher);
    // oder gleich mit den Daten initialisieren:
    std::vector<std::size_t> da_nu_hashes (boost::make_transform_iterator(v.begin(), hasher), boost::make_transform_iterator(v.end(), hasher);
    

    Und es ist nunmal nicht grundlegende Eigenschaft eines Objektes, dass es einen Hash von sich selbst erzeugen kann, das hat einfach keine öffentliche Methode zu sein.



  • ich meinte mit 10 objekten nicht 10 objekte von point sondern von objekte von 10 unterschiedlichen klassen - habe mich etwas undeutlich ausgedrückt.



  • booster schrieb:

    ich meinte mit 10 objekten nicht 10 objekte von point sondern von objekte von 10 unterschiedlichen klassen - habe mich etwas undeutlich ausgedrückt.

    Dadurch wird's mir jetzt auch nicht klarer. Wenn Du von 10 point-Objekten die Hashes haben willst ... welche "..objekte von 10 unterschiedlichen klassen.." (BTW: Shift-Taste kaputt ? 😉 ) musst Du dann anlegen ?

    Gruß,

    Simon2.


Anmelden zum Antworten