So, this question has been asked before, but I wanted a question with some of those key words in the title.
The issue is simple: How can I have a templated class, such that for each instance of the template - but not each instance of the class - there is a unique, numerical identifier?
That is, a way to differentiate:
foo<开发者_高级运维int> f1;
foo<char> f2;
classID(f1) != classID(f2);
but,
foo<int> f3;
foo<int> f4;
classID(f3) == classID(f4);
Related to:
in C++, how to use a singleton to ensure that each class has a unique integral ID?
Assigning Unique Numerical Identifiers to Instances of a Templated Class
template<class T>
class Base
{
public:
static void classID(){}
private:
T* t;
};
int main()
{
Base<int> foo;
Base<int> foo2;
Base<char> foo3;
/*
unsigned int i = reinterpret_cast<unsigned int>(Base<int>::classID);
unsigned int ii = reinterpret_cast<unsigned int>(Base<char>::classID);
unsigned int iii = reinterpret_cast<unsigned int>(Base<int>::classID);
/*/
unsigned int i = reinterpret_cast<unsigned int>(foo.classID);
unsigned int ii = reinterpret_cast<unsigned int>(foo2.classID);
unsigned int iii = reinterpret_cast<unsigned int>(foo3.classID);
//*/
return ((i != ii) + (i <= ii) + (i >= ii)) == 2;
}
That's how! It's lightweight, super easy, and doesn't use RTTI, although it uses the ridiculously unsafe reinterpret_cast.
Although, maybe I'm missing something?
I think you can just use a static function for this, and inherit its class:
struct IdCounter { static int counter; };
int IdCounter::counter;
template<typename Derived>
struct Id : IdCounter {
static int classId() {
static int id = counter++;
return id;
}
};
struct One : Id<One> { };
struct Two : Id<Two> { };
int main() { assert(One::classId() != Two::classId()); }
Of course, that won't be a static compile time constant - i don't think that is possible automatically (you would have to add those types manually to some type list like mpl::vector
). Please notice that for just comparing types for equality, you don't need all this. You just need to use is_same
(found in boost and other libraries and trivial to write) which yields a compile time constant
template<typename A, typename B>
struct is_same { static bool const value = false; };
template<typename A>
struct is_same<A, A> { static bool const value = true; };
int main() { char not_true[!is_same<One, Two>::value ? 1 : -1]; }
精彩评论