2012-12-13 237 views
3

將C字符串用作映射鍵有什麼問題嗎?C字符串映射鍵

std::map<const char*, int> imap; 

在地圖上並不重要元素的順序,所以如果他們使用std::less<const char*>下令沒關係。

我使用Visual Studio和根據MSDN(Microsoft專用):

在某些情況下,相同的字符串文字可以被「合併」,以節省空間的可執行文件。在字符串文字池中,編譯器會將對特定字符串文字的所有引用指向內存中的相同位置,而不是將每個引用點指向字符串文字的單獨實例。

它說,他們只集中在某些情況下,所以它看起來像使用字符串字面量將是一個不錯的主意訪問地圖元素:

//Could these be referring to different map elements? 
int i = imap["hello"]; 
int j = imap["hello"]; 

是否有可能超載operator==對於const char*使得實際C字符串而不是指針值將被用來確定地圖元素是相等的:

bool operator==(const char* a, const char* b) 
{ 
    return strcmp(a, b) == 0 ? true : false; 
} 

將C字符串用作映射鍵是否是個好主意?

回答

4

是否有可能超載==操作符用於爲const char *,以使實際的C字符串,而不是指針值將被用來確定地圖元素相等

不,這不是,是的,在這個問題中指出的原因並不是一個好主意,因爲您不需要char*,您可以改爲使用std::string。 (你可以提供一個自定義的比較功能 - 通過simonc指出的那樣,但我建議反對)

//Could these be referring to different map elements? 
int i = imap["hello"]; 
int j = imap["hello"]; 

是,他們甚至可以引用尚不存在的元素,但他們會由operator[]創建並進行值初始化。分配存在同樣的問題:

imap["hello"] = 0; 
imap["hello"] = 1; 

該地圖現在可以有1個或2個元素。

5

可以提供具有比較C字符串

std::map<const char*,YourType,CstrCmp>; 

bool CstrCmp::operator()(const char* a, const char* b) 
{ 
    return strcmp(a, b) < 0; 
} 
+0

比較器功能是錯誤的。我們需要它返回'a'是否小於'b';現在它返回「a」是否與「b」不同。 – Gorpik

+0

@Gorpik謝謝。看起來邁克西摩也注意到了這一點,並且打敗了我們兩人進行了糾正。 – simonc

+0

我知道比較器用於確定地圖中元素的位置,但它也用於確定兩個地圖元素是否相等?換句話說,如果你提供了一個比較器,它將被用於operator ==以確定兩個地圖元素是否相等? – user974967

1

首先,爲了引進訂購了你需要定義一個「小於」比較地圖鍵自定義比較器的地圖。一幅地圖表示,如果兩個元素都不小於另一個,則兩個元素是「等價的」。對地圖鍵使用char *是一個糟糕的主意,因爲您需要在地圖之外的某處進行內存管理。

在大多數實際情況下,當您查詢地圖時,您的關鍵字不會是文字。另一方面,如果您自己維護一個字符串文字池併爲每個文字分配一個ID,則可以將這些ID用於地圖鍵。總之,我不會依賴微軟的說法:「在某些情況下,文字可能會彙集在一起​​」。如果用文字填充地圖,並且如果用文字作爲關鍵字查詢地圖,則最好使用枚舉鍵。