2016-09-23 42 views
0

我使用typeid(ClassName).name()来获取广泛的类类型的名称。但是,我需要将其长度固定(例如8个字符)。在很多情况下,这个类是在一个命名空间中,这个字符串很长,如果我只是得到前10个字符,它就不起作用。如何获得修复大小的类名字符串

有谁知道一个好的方法来编码/解码一个字符串成一个固定大小的字符串?因为我要将字符串发送给另一台无法访问地图的机器,所以我无法真正保留一张表来将hash_code映射到一个名称。

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

好像你需要找到一个压缩算法。不知道这是否可能。 – alain

+2

这看起来很像[XY问题](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)。 – molbdnilo

+0

@molbdnilo如果你知道除了使用typeid之外的其他方法,我很乐意知道。 –

回答

0

一般来说,建立一个将任意长度的字符串映射到固定域的函数是不可能的。这违反了pigeonhole principle

提出以下建议我看来相当令人费解,但由于缺乏更大范围内的,您的问题,在这里不用...

假设您开发,通过它来运行所有名称的类,所以

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

它有两个成员:一个ctor接受一个种子,一个operator()接受一个名称字符串并返回一个8个字符的关键字符串。在你的代码中,用一些固定的,任意的种子初始化这个对象。

在内部,类对象应该包含一个unordered_map映射,对于应用了它的每个不同名称,映射它的键。显然,这个内部unordered_map将是空的。

该类对象应使用universal hash function,由构造函数中的seed伪随机选择。在一种创建通用散列函数的方法中查看this question的答案。

当调用操作员时,应检查名称是否在内部unordered_map。如果是这样,请返回找到的密钥。否则,首先使用散列函数计算密钥并将其放置在内部unordered_map中。但是,在生成新密钥时,请检查它是否与现有密钥相冲突,如果是,则引发异常。实际上,由于每个不同的名称都对应于您的代码中的一个地方,因此您呼叫typeid,不同名称的数量(例如n)最多应该是1000年。设置m为8个字符的可能范围(2 )。

碰撞的概率是〜n /(2 m),它应该很小。因此,大多数机会是不会发生冲突,也不会抛出异常。然而,如果抛出一个,则改变种子,并再次构建该程序。预期的次数,你必须这样做(初始时间后)接近0.

相关问题