Frage

Ich bin mit Boost-Implementierung einer Hash-Karte in einem Projekt gerade jetzt, und ich versuche, einen benutzerdefinierten Typen für Schlüssel zu implementieren. Ich habe vier Integer ohne Vorzeichen, die Ich mag würde in einen einzigen 128-Bit-Datentyp zu kombinieren, als Schlüssel zu verwenden.

Ich habe eine Struktur mit einem 32-Bit-Integer-Array aus vier Elementen erstellt, die als meine Speicherung dient. Um ehrlich zu sein, ich bin nicht sicher, wie Boost-der Hash-Karte funktioniert, so dass ich bin mir nicht sicher, was ich hier tue, aber ich folgte die Boost-Dokumentation ( http://www.boost.org/doc/libs/1_37_0/doc/html/hash/custom.html ) für die Erweiterung boost :: Hash, und ich erstellt eine Hash-Funktion, sowie einen benutzerdefinierten Vergleichsoperator.

Ich habe diesen benutzerdefinierten Typen in einem Header definiert. Dies ist mein Code:

#ifndef INT128_H_
#define INT128_H_

// Custom 128-bit datatype used to store and compare the results of a weakened hash operation.
struct int128
{
    unsigned int storage[4];

    /* Assignment operation that takes a 32-bit integer array of four elements.
    This makes assignment of values a shorter and less painful operation. */
    void operator=(const unsigned int input[4])
    {
        for(int i = 0; i < 4; i++)
            storage[i] = input[i];
    }
};

bool operator==(int128 const &o1, int128 const &o2)
{
    if(o1.storage[0] == o2.storage[0] && o1.storage[1] == o2.storage[1] && 
       o1.storage[2] == o2.storage[2] && o1.storage[3] == o2.storage[3])
        return true;

    return false;
}

// Hash function to make int128 work with boost::hash.
std::size_t hash_value(int128 const &input)
{
    boost::hash<unsigned long long> hasher;
    unsigned long long hashVal = input.storage[0];

    for(int i = 1; i < 3; i++)
    {
        hashVal *= 37;
        hashVal += input.storage[1];
    }

    return hasher(hashVal);
}

#endif

Nun, wenn ich tatsächlich diese Art in ungeordneter Karte des Boost, mein Code kompiliert, aber nicht zu verknüpfen. Der Linker behauptet, dass ich ein Symbol mehrfach in mehreren Objektdateien definiert. Ich würde wirklich mit dieser Karte arbeiten möchte meine 128-Bit-Typ erhalten. Irgendwelche Tipps, was ich zu vermasseln, oder ein besserer Weg, dies zu tun?

War es hilfreich?

Lösung

Die Beteiligung von ungeordneten-Karte ist fast nebensächlich zu dem Problem, das Sie stoßen. Das eigentliche Problem ist, dass Sie hash_value und operator== in jeder Datei sind definiert, die den Header oben enthält.

Sie können diese heilen, indem entweder:

  1. definieren sowohl diejenigen, die als Inline-Funktionen
  2. Just sie im Header deklariert

Wenn Sie das letztere tun (und es ist das, was Sie wollen in der Regel) finden Sie die Definitionen dieser Funktionen in eine .cpp Datei verschieben (oder was auch immer Erweiterung, die Sie verwenden für C ++ Quelldateien). Sie werden dann diese Datei kompilieren und verknüpfen das resultierende Objekt mit dem anderen Code, der den int128 Typ verwendet.

Edit: Sie können Ihren Vergleich sauberer machen, so etwas wie:

bool operator==(int128 const &o1, int128 const &o2)
{
    return o1.storage[0] == o2.storage[0] && o1.storage[1] == o2.storage[1] && 
           o1.storage[2] == o2.storage[2] && o1.storage[3] == o2.storage[3]);
}

Andere Tipps

  

Der Linker behauptet, dass ich ein Symbol haben   definierten mehrmals in mehreren   Objektdateien.

erklären, um Ihre Funktionen als inline

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top