Pergunta

Eu estou usando a implementação do impulso de um mapa de hash em um projeto agora, e eu estou tentando implementar um tipo personalizado para as chaves. Tenho quatro inteiros sem sinal que eu gostaria de combinar em um único tipo de dados de 128 bits para usar como uma chave.

Criei uma estrutura com um conjunto inteiro de 32-bit de quatro elementos, que serve como meu armazenamento. Para ser honesto, eu não sei como do impulso mapa de hash obras, então eu não sei o que estou fazendo aqui, mas eu segui a documentação Impulso ( http://www.boost.org/doc/libs/1_37_0/doc/html/hash/custom.html ) para estender boost :: hash e eu criei uma função hash, bem como um operador de comparação personalizado.

Eu tenho esse tipo personalizado definido em um cabeçalho. Este é meu 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

Agora, quando eu realmente usar este tipo de mapa não ordenada do Boost, meus compila o código, mas não link. As reivindicações vinculador que eu tenho um símbolo definido várias vezes em vários arquivos objeto. Eu realmente gostaria de obter o meu tipo de trabalho de 128 bits com este mapa. Todas as dicas sobre o que estou estragar, ou uma maneira melhor de fazer isso?

Foi útil?

Solução

O envolvimento de não-ordenada-map é quase incidental para o problema que você está encontrando. O verdadeiro problema é que você está definindo hash_value e operator== em cada arquivo que inclui o cabeçalho acima.

Você pode curar isso por qualquer:

  1. Definir tanto aqueles como funções inline
  2. Apenas declará-los no cabeçalho

Se você fazer o último (e é o que você normalmente vai querer) você vai passar as definições dessas funções em um arquivo .cpp (ou qualquer extensão que você usar para arquivos de origem C ++). Em seguida, você compilar esse arquivo, e vincular o objeto resultante com o outro código que usa o tipo int128.

Edit: Você ainda pode fazer seu aspirador de comparação, 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]);
}

Outras dicas

As reivindicações vinculador que eu tenho um símbolo definidas várias vezes em diversas arquivos objeto.

declarar suas funções como inline

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top