所以,这个问题之前已经被问过,但我想要一个标题中有一些关键词的问题。
问题很简单:我怎样才能有一个模板类,这样对于模板的每个实例——但不是类的每个实例——都有一个唯一的数字标识符?
也就是说,一种区分方法:
foo<int> f1;
foo<char> f2;
classID(f1) != classID(f2);
但,
foo<int> f3;
foo<int> f4;
classID(f3) == classID(f4);
相关:
所以,这个问题之前已经被问过,但我想要一个标题中有一些关键词的问题。
问题很简单:我怎样才能有一个模板类,这样对于模板的每个实例——但不是类的每个实例——都有一个唯一的数字标识符?
也就是说,一种区分方法:
foo<int> f1;
foo<char> f2;
classID(f1) != classID(f2);
但,
foo<int> f3;
foo<int> f4;
classID(f3) == classID(f4);
相关:
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;
}
这就是如何!它是轻量级的、超级简单的,并且不使用 RTTI,尽管它使用了非常不安全的 reinterpret_cast。
虽然,也许我错过了什么?
我认为您可以为此使用静态函数,并继承其类:
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()); }
当然,这不会是静态编译时间常数——我认为这不可能自动实现(您必须手动将这些类型添加到某些类型列表中,例如mpl::vector
)。请注意,仅比较类型是否相等,您不需要所有这些。您只需要使用is_same
(在 boost 和其他库中找到并且编写起来很简单),它会产生一个编译时间常数
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]; }