Consider the following code:
#include <iostream>
#include <cstdlib>
#include <ctime>
struct BaseClass {
static int identifier() {
static int identifier_counter = 0;
return identifier_counter++;
}
};
template <class D>
struct Class: public BaseClass {
static int identifier() {
static int class_identifier = BaseClass::identifier();
return class_identifier;
}
};
struct A: public Class<A> { };
struct B: public Class<B> { };
int main() {
std::srand(std::time(0));
int r = std::rand()%2;
if(r) {
std::cout << "A: " << A::identifier() << std::endl;
std::cout << "B: " << B::identifier() << std::endl;
} else {
std::cout << "B: " << B::identifier() << std::endl;
std::cout << "A: " << A::identifier() << std::endl;
}
}
It's a reduced, but still plausible representation of the problem.
Any derived class will have a specific, different identifier on runtime and two instances of the same type will share the same identifier. Surely a good solution for such a problem.
Unfortunately, those identifiers depend on the order on which the identifier
members are invoked (we can see it easily by running multiple times the example). In other words, given two classes A
and B
, if it happens that running twice the software their identifier
members are invoked in different order, they have different identifiers.
My problem is that, for some reasons, I need to store those identifiers somewhere and let them survive the single execution, so that I can reason on the original types once the application runs once more and decide to read those values from the storage.
An alternative would be to use hash_code from type_info
, but it suffers from other problems. Another solution would be to force the calls to the identifier
members during the bootstrap of the application, but this one also has several drawbacks.
I'd like to know if there is so far an easy to implement though still elegant solution that is completely transparent to the developer to identify types over several executions, as the one above is for the single run of the application.