2016-09-23 36 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.

相關問題