如何获得固定大小的类名称字符串

How to get a fix sized class name string

本文关键字:字符串 何获得      更新时间:2023-10-16

我使用typeid(ClassName).name()来获取广泛的类类型的名称。然而,我需要使它的长度固定(例如8字符)。在许多情况下,类是在一个命名空间,这使得字符串很长,它不工作,如果我只得到前10个字符。

有没有人知道一个好方法来编码/解码字符串成一个固定大小的字符串?我不能保留一个表来将hash_code映射到一个名称,因为我要将字符串发送到另一台无法访问映射的机器。

 template <typename ClassType> char* get_name(){
      return typeid(ClassType).name(); // ?? 
 }

一般来说,不可能构建一个将任意长度的字符串映射到固定域的函数。这违反了鸽子洞原则。

下面的建议对我来说似乎相当复杂,但考虑到你的问题缺乏更大的背景,这里是…

假设你构建了一个类来运行你所有的名字,就像这样

class compressor {
    explicit compressor(std::size_t seed);
    std::string operator()(const std::string &name) const;
}

它有两个成员:一个是带种子的tor,一个是带名称字符串的operator(),并返回一个8字符的密钥字符串。在你的代码中,用一些固定的、任意的种子初始化这个对象。

在内部,类对象应该保存一个unordered_map映射,对于应用了它的每个不同的名称,它被映射到的键。一开始,很明显,这个内部的unordered_map将是空的。

类对象应该使用通用散列函数,由构造函数中的seed伪随机选择。下面是创建通用散列函数的一种方法。

当操作符被调用时,它应该检查名称是否在内部unordered_map中。如果是,返回为它找到的键。否则,首先使用散列函数计算键并将其放入内部unordered_map中。但是,在生成新键时,请检查它是否与现有键冲突,如果冲突,则抛出异常。

实际上,由于每个不同的名称对应于代码中调用typeid的位置,因此不同名称的数量(例如n)最多应该在1000个以内。设置m为8个字符的可能范围(264)。

碰撞的概率是~n2/(2m),这应该是很小的。因此,大多数情况下不会发生冲突,也不会抛出异常。但是,如果抛出了一个,则更改种子,并重新构建程序。在初始时间之后,您需要执行此操作的预期次数接近于0。