Utilisez le type de données (type de classe) comme clé dans une carte

j'ai la classe Base et les classes Derived_1 , Derived_2 ... J'ai besoin de classes dérivées pour avoir une id. Ces ID sont utilisés pour d'autres recherches, etc, et ont donc besoin d'être consécutifs (pas juste quelques nombres aléatoires). Parce que les classes dérivées sont créées par l'utilisateur, id ne peut pas être membre de Derived_N . Alors j'ai inventé la classe DerivedType .

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

maintenant je veux créer une correspondance entre Derived_N et DerivedType . Chaque fois que Derived_N est créé, ce mapping regarde si DerivedType pour particulier Derived_N existe déjà et le renvoie, sinon créer nouveau et stocke dans la carte.

question actuelle: Est-il possible d'utiliser std::map avec type de données comme clé à la carte? Je n'ai peur d'aucune solution de template-metaprogram. Ou y a-t-il une façon élégante d'atteindre mon but?

modifier de type Date - >Type de données, je veux dire comme ClassType, je suis désolé :)

je veux l'utiliser comme:

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

chaque instance de Derived_N (avec le même "N") devrait avoir le même id par L'intermédiaire de DerivedType

EDIT2 - MY ANSWER J'ai trouvé une meilleure solution à mon problème... C'est ainsi:

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

puisque ma question était comment utiliser datatype dans une carte, je vais marquer certains des vôtres des réponses, je vous remercie

24
demandé sur relaxxx 2012-03-25 14:17:56

3 réponses

C++11 résout ce problème en fournissant std::type_index , dans <typeindex> , qui est un objet copiable, comparable et hachable construit à partir d'un objet std::type_info qui peut être utilisé comme clé dans les conteneurs associatifs.

(l'implémentation est assez simple, donc même si vous n'avez pas C++11 Vous-Même, vous pouvez voler l'implémentation de, disons GCC 4.7, et l'utiliser dans votre propre code.)

#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;
}
49
répondu Kerrek SB 2012-03-25 10:52:25

Vous pouvez utiliser typeid(object) directement, puisqu'il est type_info::before , qui peut être utilisé comme comparateur si vous utilisez type_info clé dans la carte, voir Ce qui est " type_info::avant`? . Pas besoin de .name() .

13
répondu eudoxos 2017-05-23 11:54:59

vous pouvez utiliser n'importe quel type ou classe que vous voulez comme la clé de std::map , à condition que vous donniez aux arguments de modèle une fonction de comparaison qui lui dit comment trier l'arbre sous-jacent.

la chose la plus facile à faire IMHO de représenter les dates comme des clés, est de les convertir en horodateurs unix, mais peu importe ce que la représentation de classe d'entre eux peuvent être, il suffit de fournir une fonction de comparaison à la définition de la carte et vous êtes bon pour aller.

0
répondu Not_a_Golfer 2012-03-25 10:21:18