我有很多课程, B1 B2 ...来自同一个名为 A 的课程。
我想创建一个函数
getId<B1>() , getId<B2>() , ...
为每个类返回唯一的int,并且结果与
一致get_id(new B1()) , get_id(new B2()) ....
换句话说,
getId<Bi>() == get_id(new Bi()) .... for every i (1)
getId<Bi>() != getId<Bj>() .... when i!=j (2)
B1 B2只是一种符号,它们是现实生活中没有整数的较长名称。
如何实现这两个功能?
要求:
1.我不需要编辑所有Bi.h(B1 B2 ...类),因为它们很多
2.不允许手动分配每个类的分配整数,因为它很繁琐
3.不能使用typeid或dynamic_cast,因为它很慢(我试过。)
4.模板没问题
5.非确定性是好的
6.(奖金)如果生成的整数是低值(例如B1 = 1,B2 = 2 ......),那就太好了。
结果(整数)将用于散列函数。
我搜索过,但找不到符合(1)和(2)两种情况的解决方案 例如,Efficient way to generate id unique to class?没有足够的帮助。
答案 0 :(得分:1)
我的回答并不是一个花哨的模板,因为我认为这已经在你链接的另一个帖子中提供,说它不够好。但是我确实有办法解决你的困境,即使我正在弯曲一些要求。
您有一个基类,以及许多虚拟子类。我将假设virtual int get_id()const = 0;是一种可能性,因为它已经是一个虚拟基础。这就是大多数人会立即做的事情,但是你在大型现有系统上进行改造,并且不能手动分配所有这些id。
如果我们只有一台电脑,那太麻烦了......哦等等。
您可以通过在标题中搜索grep“:public class A”之类的内容来获取所有类名,或者如果它们过于分散且编写不一致以便从标题中轻松获取它们,那么只需将get_id设为纯净, grep编译器错误消息以获取所有这些类名。将输出转储到文件。现在,编写一个快速而脏的python脚本来读取该输出中的每一行,然后编写
print "int {}::get_id() const {{ return {}; }}".format(classname, linenumber)
我省略了使用re拉出classname的细节,因为你可以在grep或脚本中执行此操作或编写一个简短的c ++帮助器。关键是,你可以将它输出到一个新的cpp文件,并且(右边包括),你现在已经自动为每个类分配了id。
它不会将id分配给新类,但至少从现在开始不会太繁琐,特别是如果你保持get_id纯。
答案 1 :(得分:0)
您希望如何使用它并不完全清楚,但以下内容可满足您的所有要求:
#include <tuple>
struct A {};
struct B0 : A {};
struct B1 : A {};
struct B2 : A {};
struct B3 : A {};
void get_id(...) {}
// Just register your types here:
using types = std::tuple<B0, B1, B2, B3>;
template <int N>
void getId() {
using T = typename std::tuple_element<N, types>::type;
get_id(new T()); // This is leaking memory since there is no delete anywhere
}
int main() {
getId<0>(); // equivalent to get_id(new B0());
getId<1>(); // equivalent to get_id(new B1());
getId<2>(); // equivalent to get_id(new B2());
getId<3>(); // equivalent to get_id(new B3());
}
如果您想知道给定类型there are ways of doing that的索引是什么。