Reputation: 7824
I have class Base
and classes Derived_1
, Derived_2
...
I need derived classes to have an id. Those ids are used for further lookups etc, and thus need to be consecutive (no just some random numbers). Because derived classes are created by user, id can not be member of Derived_N
. So I came up with DerivedType
class.
class DerivedType
{
static unsigned id;
unsigned m_id;
public:
DerivedType() : m_id(id++) { }
}
Now I want to create a mapping between Derived_N
and DerivedType
.
Whenever Derived_N
is created, this mapping looks if DerivedType
for particular Derived_N
already exist and returns it, otherwise create new and stores in the map.
Actual question:
Is there any way to use std::map
with data type as key in the map?
I am not afraid of any template-metaprogram solution.
Or is there elegant way how to achieve my goal?
edit Date type -> Data type, I mean like ClassType, I am sorry :)
I want to use it like:
Derived_5 d;
DerivedType dt = getType(d); //Derived_5 is looked up in map, returning particular DerivedType
dt.getId();
every instance of Derived_N
(with same 'N') should have the same id throu DerivedType
EDIT2 - MY ANSWER I found better solution for my problem... It is like this:
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; }
};
since my question was how to use datatype in a map, I will mark some of yours answers, thank you
Upvotes: 45
Views: 31293
Reputation: 476950
C++11 solves this by providing std::type_index
, in <typeindex>
, which is a copyable, comparable and hashable object constructed from a std::type_info
object that can be used as the key in associative containers.
(The implementation is fairly simple, so even if you don't have C++11 yourself, you could steal the implementation from, say GCC 4.7, and use that in your own 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;
}
Upvotes: 89
Reputation: 19065
You can use typeid(object)
directly, since there is type_info::before
, which can be used as comparator if you use type_info as key in the map, see What is `type_info::before` useful for?. No need to get .name()
.
Upvotes: 14
Reputation: 49187
You can use whatever type or class you want as the key to std::map
, provided you give the template arguments a compare function that tells it how to sort the underlying tree.
The easiest thing to do IMHO to represent dates as keys, is to convert them to unix timestamps, but no matter what the class representation of them may be, just provide a comparison function to the map's definition and you're good to go.
Upvotes: -2