2012-03-25 10 views
20

Tengo clase Base y clases Derived_1, Derived_2 ... Necesito clases derivadas para tener una identificación. Esos ids se utilizan para búsquedas posteriores, etc., y por lo tanto deben ser consecutivos (no solo algunos números aleatorios). Como las clases derivadas las crea el usuario, el ID no puede ser miembro de Derived_N. Así que se me ocurrió la clase DerivedType.Usar tipo de datos (tipo de clase) como clave en un mapa

class DerivedType 
{ 
    static unsigned id; 
    unsigned m_id; 
public: 
    DerivedType() : m_id(id++) { } 
} 

Ahora quiero crear una correlación entre Derived_N y DerivedType. Siempre que se cree Derived_N, esta asignación se ve si DerivedType para el particular Derived_N ya existe y la devuelve; de ​​lo contrario, cree una nueva ubicación y almacene en el mapa. ¿Hay alguna manera de utilizar std::map con el tipo de datos como clave en el mapa: pregunta real

? No le temo a ninguna solución de plantilla-metaprograma. ¿O hay una forma elegante de lograr mi objetivo?

editar texto Fecha -> Tipo de datos, es decir, como ClassType, lo siento :)

quiero usarlo como:

Derived_5 d; 
DerivedType dt = getType(d); //Derived_5 is looked up in map, returning particular DerivedType 
dt.getId(); 

cada instancia de Derived_N (con mismo ' N ') debe tener el mismo ID throu DerivedType

Edit2 - mi respuesta he encontrado mejor solución para mi problema ... es li ke esto:

atomic_counter s_nextEventClassID; 

typedef int cid_t; 

template<class EventClass> 
class EventClassID 
{ 
public: 
    static cid_t getID() 
    { 
     static cid_t classID = EventClassID::next(); 
     return classID; 
    } 

    static cid_t next() { return ++s_nextEventClassID; } 
}; 

ya que mi pregunta era cómo utilizar el tipo de datos en un mapa, que marcará algunos de los suyos respuestas, gracias

Respuesta

43

C++ 11 resuelve esto proporcionando std::type_index, en <typeindex>, que es un objeto copiables, comparable y hashable construido a partir de un objeto std::type_info que puede ser usado como la clave en contenedores asociativos.

(La implementación es bastante simple, por lo que incluso si usted no tiene C++ 11 usted mismo, podría robar la implementación de, digamos GCC 4.7, y usar eso en su propio código.)

#include <typeindex> 
#include <typeinfo> 
#include <unordered_map> 

typedef std::unordered_map<std::type_index, int> tmap; 

int main() 
{ 
    tmap m; 
    m[typeid(main)] = 12; 
    m[typeid(tmap)] = 15; 
} 
+1

esta debería ser la respuesta aceptada – jupp0r

+0

Muy buena respuesta que utiliza el moderno C++ – Anonymous

0

Se puede utilizar cualquier tipo o clase que desea como la clave para std::map , siempre que proporcione a los argumentos de la plantilla una función de comparación que le indique cómo ordenar el árbol subyacente.

Lo más fácil de hacer en mi humilde posición para representar fechas como claves, es convertirlas a marcas de tiempo de Unix, pero no importa cuál sea la representación de clase de ellas, simplemente proporcione una función de comparación a la definición del mapa y está bien ir.

13

Puede usar typeid(object) directamente, ya que hay type_info::before, que puede usarse como comparador si utiliza type_info como clave en el mapa, consulte What is `type_info::before` useful for?. No es necesario obtener .name().

Cuestiones relacionadas