通过其值在地图中查找元素

时间:2015-09-25 10:20:05

标签: c++ dictionary

我正在创建一个HandleManager,其目的是简单地将Handle s(typedef long long int}映射到string。目的是使用Handle的对象也可以通过string标识,如果它有助于用户记住该对象。在这种情况下,在这张地图中:

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

该对中的两种类型都是键,只​​要它们可用于识别任何东西。到目前为止,除了需要获取Handle的代码之外,所有内容都已编译完成。目的是当用户像这样分配string时:

handle("myHandle"); 

随机生成Handle,然后传递的string在前面的地图中与之配对。我现在想要的是能够根据传递的Handle获得与string配对的string

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获取

4 个答案:

答案 0 :(得分:6)

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和lambdas是C ++ 11,而通用lambdas是C ++ 14,所以如果你被困在那里,请用它们代替一个旧的编译器。

答案 1 :(得分:5)

您可以使用成员函数find仅搜索密钥。要搜索值,可以使用带有lambda函数的std::find_if(如果使用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>。在这种情况下,您必须确保在两个地图中执行插入,删除等操作以保持同步。

答案 2 :(得分:2)

  

但是由于一些奇怪的原因,编译器抱怨这个:

当然可以,find函数用于按键查找,而您却没有这样做。

要查找值,您需要访问每个元素,直到找到它(或使用将值映射回键的双向映射,例如Boost.Bimap)。

答案 3 :(得分:0)

基于answer from @TartanLlama(*):

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

(*):因为似乎无法格式化注释中的代码。