Domanda

Sto usando l'implementazione di spinta di una mappa hash in un progetto in questo momento, e sto cercando di attuare un tipo personalizzato per le chiavi. Ho quattro numeri interi senza segno che mi piacerebbe combinare in un unico tipo di dati a 128 bit da utilizzare come chiave.

Ho creato una struttura con un allineamento intero a 32 bit di quattro elementi, che serve come il mio stoccaggio. Per essere onesti, io non sono sicuro di come mappa di hash di Boost funziona, quindi non sono sicuro di quello che sto facendo qui, ma ho seguito la documentazione Boost ( http://www.boost.org/doc/libs/1_37_0/doc/html/hash/custom.html ) per estendere boost :: hash, e ho creato una funzione di hash, così come un operatore di confronto personalizzato.

ho questo tipo personalizzato definito in un colpo di testa. Questo è il mio codice:

#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

Ora, quando io in realtà uso questo tipo di carta non ordinata di Boost, il mio codice compila, ma non riesce a collegarsi. Il linker sostiene che ho un simbolo definito più volte in diversi file oggetto. Mi piacerebbe davvero ottenere il mio tipo 128-bit a lavorare con questa mappa. Eventuali suggerimenti su quello che sto strizzando, o un modo migliore per fare questo?

È stato utile?

Soluzione

Il coinvolgimento di non ordinata-mappa è quasi incidentale al problema incontrato. Il vero problema è che si sta definendo hash_value e operator== in ogni file che include l'intestazione di cui sopra.

Si può curare questo uno:

  1. Definizione sia quelli come funzioni inline
  2. Basta dichiarandoli nell'intestazione

Se si fa il secondo (ed è ciò che si desidera in genere) si sposta le definizioni di queste funzioni in un file .cpp (o qualunque estensione che si utilizza per i file di origine C ++). Potrai quindi compila il file, e collega l'oggetto risultante con l'altro codice che utilizza il tipo int128.

Edit: Si può ancora fare il vostro più pulita confronto, qualcosa di simile:

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

Altri suggerimenti

  

Il linker sostiene che ho un simbolo   definiti più volte in diversi   file oggetto.

dichiarare le funzioni come inline

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top