2015-09-25 19 views
-2

我創建查找在地圖中的元素的HandleManager,其目的是簡單地映射Handle秒(這是一個long long inttypedef)至string秒。目的是爲了使使用Handle的物體也可以通過string識別,如果它幫助用戶記住物體。在這種情況下,在該地圖中:通過其值

typedef std::unordered_map<Handle, std::string> HandleMap; 

這兩種類型都是鑰匙,只要它們可以用來識別任何東西。到目前爲止,除了需要獲得Handle的代碼之外,所有內容都已編譯完成。目的是使得當用戶分配一個string像這樣:

handle("myHandle"); 

Handle一個隨機產生,然後通過string在前述的圖配對它。我現在想要的是能夠獲取與基於該stringstring傳遞配對的Handle

Handle HandleManager::id(const std::string &name) 
{ 
    HandleMap::iterator it = pHandles.find(name); 

    if (it != pHandles.end()) 
     return it->first; 
    return -1; 
} 

但由於某些奇怪的原因,編譯器會抱怨這樣的:

HandleManager.cpp:48:45: error: no matching function for call to ‘std::unordered_map<long long int, std::basic_string<char> >::find(const string&)’ 

在上述地圖中,string是值,Handle是關鍵。那麼如何根據其中包含的unordered_map獲得密鑰

+2

也許你需要[boost :: bimap](http://www.boost.org/doc/libs/1_59_0/libs/bimap/doc/html/index.html) – Jepessen

+0

唉,你必須寫這樣的功能你自己。 – SingerOfTheFall

+0

你不能使用'std :: unordered_map',唯一的方法是遍歷所有條目。 IIRC增強提供了一種類型,允許按值查找。 –

回答

4

您可以使用成員函數find來僅搜索密鑰。要搜索的值,你可以使用一個std::find_if與lambda函數(如果你使用C++ 11),或穿越地圖(確定在以前的C++版本):

for (HandleMap::const_iterator it = map.begin(); it != map.end(); ++it) { 
    if (it->second == name) return it->first; 
} 
// or value not found 

。另一方面,如果搜索值是非常常見的操作,則可能需要兩張地圖:std::unordered_map<Handle, std::string>std::unordered_map<std::string, Handle>。在這種情況下,您必須確保您在兩個地圖中執行插入,刪除等操作,以保持同步。

+0

謝謝,這就是我一直在尋找的! – Poriferous

2

但由於某些奇怪的原因,編譯器會抱怨這樣的:

當然它當中,find功能是查找起來的關鍵和你沒有這樣做。

要找到你需要的,直到你找到它訪問的每一個元素(或使用雙向映射它映射值回鍵,例如Boost.Bimap)的值。

3

std::unordered_map::find對密鑰操作,而不是值。您可以使用std::find_if

Handle HandleManager::id(const std::string &name) 
{ 
    auto it = std::find_if(std::begin(pHandles), std::end(pHandles), 
          [](auto&& p) { return p->second == name; }); 

    if (it == std::end(pHandles)) 
     return -1; 

    return it->first 
} 

注意autostd::beginstd::end和lambda表達式是C++ 11和通用Lambda表達式是C++ 14,所以替代者淘汰,如果你繼續使用舊的編譯器。