Подтвердить что ты не робот

Использовать тип данных (тип класса) в качестве ключа на карте

У меня есть класс Base и классы Derived_1, Derived_2... Мне нужны производные классы, чтобы иметь id. Эти идентификаторы используются для дальнейших поисков и т.д. И, следовательно, должны быть последовательными (не просто некоторые случайные числа). Поскольку производные классы создаются пользователем, идентификатор не может быть членом Derived_N. Поэтому я придумал класс DerivedType.

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

Теперь я хочу создать сопоставление между Derived_N и DerivedType. Всякий раз, когда создается Derived_N, это сопоставление выглядит, если DerivedType для конкретного Derived_N уже существует и возвращает его, в противном случае создавайте новые и сохраняйте на карте.

Актуальный вопрос: Можно ли использовать std::map с типом данных как ключ на карте? Я не боюсь никакого решения шаблона-метапрограммы. Или есть элегантный способ достижения моей цели?

изменить Тип даты → Тип данных, я имею в виду как ClassType, извините:)

Я хочу использовать его как:

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

каждый экземпляр Derived_N (с тем же "N" ) должен иметь один и тот же идентификатор DerivedType

EDIT2 - МОЙ ОТВЕТ Я нашел лучшее решение для своей проблемы... Это примерно так:

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

так как мой вопрос заключался в том, как использовать тип данных на карте, я отмечу некоторые ваши ответы, спасибо

4b9b3361

Ответ 1

С++ 11 разрешает это, предоставляя std::type_index, в <typeindex>, который является копируемым, сопоставимым и хешируемым объектом, построенным из объекта std::type_info, который может использоваться как ключ в ассоциативных контейнерах.

(Реализация довольно проста, поэтому, даже если у вас нет С++ 11, вы можете украсть реализацию, скажем, GCC 4.7, и использовать ее в своем собственном коде.)

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

Ответ 2

Вы можете напрямую использовать typeid(object), так как существует type_info::before, который может использоваться как компаратор, если вы используете key_info как ключ на карте, см. Что такое` type_info:: до `полезно для?. Не нужно получать .name().

Ответ 3

Вы можете использовать любой тип или класс в качестве ключа для std::map, если вы дадите аргументам шаблона функцию сравнения, которая сообщает ему, как сортировать базовое дерево.

Проще всего сделать IMHO для представления дат как ключей, это преобразовать их в временные метки unix, но независимо от их представления класса просто предоставить функцию сравнения для определения карты, и вы хорошо перейти.