使用函数地址的模板类的唯一数字ID

时间:2010-02-01 07:43:21

标签: c++ class templates metaprogramming unique-id

所以,之前已经问过这个问题,但我想在标题中提出一些关键词的问题。

问题很简单:我怎样才能有一个模板化的类,这样对于模板的每个实例 - 而不是每个类的实例 - 都有一个唯一的数字标识符?

这是一种区分方式:

foo<int> f1;
foo<char> f2;
classID(f1) != classID(f2);

但是,

foo<int> f3;
foo<int> f4;
classID(f3) == classID(f4);

相关:

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

2 个答案:

答案 0 :(得分:3)

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。

虽然,也许我错过了什么?

答案 1 :(得分:1)

我认为您可以为此使用静态函数,并继承其类:

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]; }