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

C++ 使用函数地址的模板化类的唯一数字ID,c++,class,templates,metaprogramming,unique-id,C++,Class,Templates,Metaprogramming,Unique Id,以前有人问过这个问题,但我想问一个标题中有一些关键词的问题 问题很简单:我如何拥有一个模板化的类,这样对于模板的每个实例——而不是类的每个实例——都有一个唯一的数字标识符 也就是说,一种区分: foo<int> f1; foo<char> f2; classID(f1) != classID(f2); foo-f1; foo-f2; classID(f1)!=classID(f2); 但是, foof3; 富f4; classID(f3)=classID(f4);

以前有人问过这个问题,但我想问一个标题中有一些关键词的问题

问题很简单:我如何拥有一个模板化的类,这样对于模板的每个实例——而不是类的每个实例——都有一个唯一的数字标识符

也就是说,一种区分:

foo<int> f1;
foo<char> f2;
classID(f1) != classID(f2);
foo-f1;
foo-f2;
classID(f1)!=classID(f2);
但是,

foof3;
富f4;
classID(f3)=classID(f4);
有关:

模板
阶级基础
{
公众:
静态void classID(){}
私人:
T*T;
};
int main()
{
基辅;
基础食物2;
基础食物3;
/*
unsigned int i=重新解释强制转换(Base::classID);
unsigned int ii=重新解释转换(Base::classID);
unsigned int iii=重新解释强制转换(Base::classID);
/*/
无符号整数i=重新解释(foo.classID);
unsigned int ii=重新解释(foo2.classID);
无符号整数iii=重新解释铸型(foo3.classID);
//*/
返回((i!=ii)+(i=ii))==2;
}
就是这样!它重量轻,超级简单,并且不使用RTTI,尽管它使用了可笑的不安全的reinterpret_演员阵容

不过,也许我遗漏了什么?

模板
阶级基础
{
公众:
静态void classID(){}
私人:
T*T;
};
int main()
{
基辅;
基础食物2;
基础食物3;
/*
unsigned int i=重新解释强制转换(Base::classID);
unsigned int ii=重新解释转换(Base::classID);
unsigned int iii=重新解释强制转换(Base::classID);
/*/
无符号整数i=重新解释(foo.classID);
unsigned int ii=重新解释(foo2.classID);
无符号整数iii=重新解释铸型(foo3.classID);
//*/
返回((i!=ii)+(i=ii))==2;
}
就是这样!它重量轻,超级简单,并且不使用RTTI,尽管它使用了可笑的不安全的reinterpret_演员阵容


虽然,也许我遗漏了什么?

我认为您可以使用一个静态函数,并继承它的类:

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()); }

我认为您可以使用一个静态函数,并继承它的类:

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()); }

顺便说一句,
的问题是它不支持>或者它满足所有要求,但是,您指出它不是静态编译时常量?你知道我自己的答案是什么吗?(我想是的,但我不确定如何测试它。)AFAIK,
的问题是它不支持>或者它满足所有要求,但是,您指出它不是静态编译时常量?你知道我自己的答案是什么吗?(我想是的,但我不确定如何测试。)我选择了我自己的答案,因为它是a)更简单,b)静态编译时常量,afaik。我用VS 2015测试了它,它在为调试而编译时有效,但在为发布而编译时无效。编译发行版时,优化器将所有classID()函数合并为一个函数。所以foo.classID==foo2.classID==foo3.classID。我选择了自己的答案,因为它是a)更简单,b)静态编译时常量afaik。我用VS 2015测试了它,它在编译用于调试时有效,但在编译用于发布时无效。编译发行版时,优化器将所有classID()函数合并为一个函数。所以foo.classID==foo2.classID==foo3.classID。
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()); }
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]; }