2010-10-11 7 views
5

que tienen una clase como esta:¿Puedo usar una variable miembro como clave para hash_set/hash_map?

class Foo 
{ 
    long long Id; 
    string x; 
    string y; 
    // other member variables and functions 
}; 

me gustaría guardar esto en un hash_set (o hash_map), pero el uso de la variable miembro Id como la clave para la inserción y búsqueda. No estoy seguro de cómo puedo hacer esto. Pensé en las siguientes formas, pero ninguna de ellas es realmente buena:

1) Puedo escribir una función hash personalizada que pellizque el objeto usando Id, pero luego no puedo usar el método find() en hash_set para busca el elemento por Id (long long) ya que requerirá que se pase un objeto Foo.

2) Puedo duplicar el Id. Y crear un hash_map<long long, Foo> en lugar de un hash_set<long long, Foo> pero tengo 100 millones de instancias de estos objetos, así que prefiero no duplicar el campo Id.

3) que se puede mover el campo ID fuera del Foo y luego hago hash_map<long long, Foo>, pero sería especie de desordenado ya que la ID se utiliza internamente por la clase y sería mejor mantenerlo con Foo.

¿Alguna idea? Lo que estoy buscando es una forma de almacenar objetos Foo, pero ser capaz de buscarlos en el hash_set usando un long long (por Id).

Gracias!

+0

Ir con el tercer enfoque. – Grozz

+0

El segundo está bien también. – sellibitze

+0

¿Cuál es el patrón de uso para esto? ¿Lo está configurando una vez y luego solo leyó o sigue modificando el conjunto? – sbi

Respuesta

0

esto puede no ser una solución muy elegante, pero funciona: definir un operator < (y operator == así, como se sugiere Cashcow) para su clase que ordena los objetos basándose en el campo Id, a continuación, cuando se quiere hacer una find , pase un objeto ficticio que contenga el Id que está buscando.

+0

Funciona muy bien para un conjunto estándar o mapa, no tan bueno para los contenedores basados ​​en hash. El 'operador ', quiero decir. –

+0

¿Por qué no? Pensé que los contenedores basados ​​en hash todavía dependen de 'operator 'para finalmente asegurar que dos objetos sean iguales. – casablanca

+0

Ambos 'hash_map' y' unordered_map' parecen tomar un functor de comparación para la igualdad, no menos de. –

0

1) Puedo escribir una función hash a medida que desmenuzar el objeto con la Id, pero entonces no puedo usar el find() método de hash_set para buscar el elemento por Id (larga largo) ya que se requieren un objeto Foo para ser transferido.

Este es un problema común con el mapa estándar y el conjunto de contenedores. Agregue un constructor o miembro estático que crea un objeto de comparación, un objeto con solo el miembro clave válido.

0

La opción 2 es la mejor opción entre las tres que diste. Si está preparado, puede escribir un hash_set personalizado (incluso un envoltorio alrededor del habitual) para proporcionar lo que desea. En ese caso, preferiría la opción 1. Podría agregar fácilmente una función de búsqueda que solo tome el valor de la clave y la adapte para usar la función de búsqueda interna de manera adecuada, brindándole todos los beneficios.

0

no tengo mucha experiencia con él, pero boost :: multiindex se construye en la parte superior de impulso :: picadillo de forma predeterminada, y cuenta con el apoyo explícito para buscar un objeto en un hash utilizando sólo una clave que se encuentran en el objeto.

0

Si no encuentra una solución real para los contenedores hash_set/hash_map, es posible que desee considerar el uso de la aplicación tabla hash de uthash, que apoya su caso de uso directamente. Es C y está basado en macros, pero es una de las implementaciones de tablas hash más populares que existen.

Cuestiones relacionadas