Pregunta

Estoy usando la aplicación de Boost de un mapa hash en un proyecto en este momento, y yo estoy tratando de poner en práctica un tipo personalizado para las llaves. Tengo cuatro enteros sin signo, que me gustaría combinar en un solo tipo de datos de 128 bits para usar como clave.

He creado una estructura con una matriz de enteros de 32 bits de cuatro elementos, que sirve como mi almacenamiento. Para ser honesto, no estoy seguro de cómo mapa hash de Boost funciona, así que no estoy seguro de lo que estoy haciendo aquí, pero he seguido la documentación Boost ( http://www.boost.org/doc/libs/1_37_0/doc/html/hash/custom.html ) para extender impulso :: hachís, y creado una función hash, así como un operador de comparación personalizado.

Tengo este tipo personalizado definido en un encabezado. Este es mi código:

#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

Ahora, cuando en realidad utilizar este tipo de mapa no ordenada de Boost, mi código se compila, pero no se enlaza. El enlazador afirma que tengo un símbolo definido varias veces en varios archivos objeto. Realmente me gustaría obtener mi tipo de 128 bits que funciona con este mapa. ¿Algún consejo sobre lo que estoy metiendo la pata, o una mejor manera de hacer esto?

¿Fue útil?

Solución

La participación de no ordenada-mapa es casi incidental al problema que está encontrando. El verdadero problema es que se está definiendo hash_value y operator== en todos los archivos que incluye el encabezado anterior.

Puede curar esto ya sea:

  1. Definición de tanto los que como funciones en línea
  2. Sólo se declara en la cabecera

Si hace esto último (y es lo que normalmente querrá) usted se moverá las definiciones de esas funciones en un archivo .cpp (o cualquier extensión que utiliza para archivos de código fuente en C ++). A continuación, compilar ese archivo, y vincula el objeto resultante con el otro código que utiliza el tipo de int128.

Editar: Usted todavía puede hacer su limpiador de comparación, algo como:

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

Otros consejos

  

El enlazador afirma que tengo un símbolo   definidos varias veces en varios   ficheros objeto.

declarar sus funciones como inline

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top