I need a way to identify a unique combination of template types that gives me an easily indexable identifier.
I have the following class:
#include <cstdint>
typedef std::uint32_t IDType;
template<class T>
class TypeIdGenerator
{
private:
static IDType m_count;
public:
template<class U>
static IDType GetNewID()
{
static const IDType idCounter = m_count++;
return idCounter;
}
};
template<class T> IDType TypeIdGenerator<T>::m_count = 0;
Which works, but when utilized across dll and exe, each "instance" in each process resets the count, so if in the .dll I have:
IDType id = TypeIdGenerator<A>::GetNewID<B>();
It will be a different value to the same call made in the .exe with the same two classes:
IDType id = TypeIdGenerator<A>::GetNewID<B>();
Of course, this only happens if the types for different classes are generated in different orders.
I understand that the static members are static across each process, and the dll is another process, so how else can I easily retrieve a unique id that's consistent?
I'd prefer to use standard methods, no special compiler extensions or flags etc.
EDIT: More info on my use case.
I have a template class that holds another type so I can operate on arbitrary data using that template type. Very simplified:
class ComponentBase
{
public:
virtual ~ComponentBase() {}
virtual void DestroyData(unsigned char* data) const noexcept = 0;
virtual void MoveData(unsigned char* source, unsigned char* destination) const = 0;
virtual void ConstructData(unsigned char* data) const = 0;
};
template<class C>
class Component : public ComponentBase
{
public:
typedef C type;
virtual void DestroyData(unsigned char* data) const noexcept override
{
C* dataLocation = std::launder(reinterpret_cast<C*>(data));
dataLocation->~C();
}
virtual void MoveData(unsigned char* source, unsigned char* destination) const override
{
new (&destination[0]) C(std::move(*reinterpret_cast<C*>(source)));
}
virtual void ConstructData(unsigned char* data) const override
{
new (&data[0]) C(*m_component);
}
};
This is because instances of A or B need to be stored alongside each other in unsigned char* arrays. By storing a map of std::unordered_map<IDType,ComponentBase*>s I can keep access to all of the constructors, destructors, move operators etc.
I have a container that provides me information of which index in an unsigned char* is IDType for A or B etc.
So when operating on my data, I would have a container of std::vector<IDType> which from beginning to end provides me with every type stored in unsigned char* arbitrary.
I can use the IDType to lookup my unordered_map<IDType, ComponentBase*> so that I can operate on the type stored in arbitrary.
Obviously it's a little more involved than that or I'd just store the ComponentBase*s, but that's the general gist of why I need to be able to generate consistent type ids of some indexable type. Consistent only during the same execution of my program, not between different executions (though that would be a bonus).
I am using MingW64 delivered through MSYS2.