如何从地图中获取值?

时间:2012-05-22 09:54:46

标签: c++ dictionary stdmap

我有一个名为map的{​​{1}},如下所示:

valueMap

然后我通过引用将这个地图传递给一个函数:

typedef std::map<std::string, std::string>MAP;
MAP valueMap;
...
// Entering data.

如何从地图中获取值,该值作为对函数的引用传递?

6 个答案:

答案 0 :(得分:70)

不幸的是std::map::operator[]是一个非const成员函数,你有一个const引用。

您需要更改function的签名或执行:

MAP::const_iterator pos = map.find("string");
if (pos == map.end()) {
    //handle the error
} else {
    std::string value = pos->second;
    ...
}

operator[]通过向地图添加默认构造的值并返回对它的引用来处理错误。当你拥有的只是一个const引用时,这是没用的,所以你需要做一些不同的事情。

如果您的程序逻辑以某种方式保证string value = map.find("string")->second;已经是关键,那么可以忽略这种可能性并编写"string"。显而易见的问题是,如果你错了,你会得到未定义的行为。

答案 1 :(得分:18)

如果缺少键

map.at(“key”)会抛出异常

  

如果k与容器中任何元素的键不匹配,则   函数抛出out_of_range异常。

http://www.cplusplus.com/reference/map/map/at/

答案 2 :(得分:0)

史蒂夫·杰西普(Steve Jessop)的answer解释得很好,为什么不能在std::map::operator[]上使用const std::map Gabe Rainbow的 answer提出了一个不错的选择。我只想提供一些有关如何使用map::at()的示例代码。因此,这是您的function()的增强示例:

void function(const MAP &map, const std::string &findMe) {
    try {
        const std::string& value = map.at(findMe);
        std::cout << "Value of key \"" << findMe.c_str() << "\": " << value.c_str() << std::endl;
        // TODO: Handle the element found.
    }
    catch (const std::out_of_range&) {
        std::cout << "Key \"" << findMe.c_str() << "\" not found" << std::endl;
        // TODO: Deal with the missing element.
    }
}

这是一个示例main()函数:

int main() {
    MAP valueMap;
    valueMap["string"] = "abc";
    function(valueMap, "string");
    function(valueMap, "strong");
    return 0;
}

输出:

  

键“字符串”的值:abc
  找不到键“ strong”

Code on Ideone

答案 3 :(得分:0)

  

如何从映射中获取值,该值作为对函数的引用而传递?

好吧,您可以将其作为参考。 The standard reference wrapper即是。

typedef std::map<std::string, std::string> MAP;
// create your map reference type
using map_ref_t = std::reference_wrapper<MAP>;

// use it 
void function(map_ref_t map_r)
{
    // get to the map from inside the
    // std::reference_wrapper
    // see the alternatives behind that link
    MAP & the_map = map_r;
    // take the value from the map
    // by reference
    auto & value_r = the_map["key"];
    // change it, "in place"
    value_r = "new!";
}

和测试。

    void test_ref_to_map() {

    MAP valueMap;
    valueMap["key"] = "value";
    // pass it by reference
    function(valueMap);
    // check that the value has changed
    assert( "new!" == valueMap["key"] );
}

我认为这很好而且很简单。享受...

答案 4 :(得分:0)

主要问题是运算符[]用于在映射中插入值和从中读取值,因此它不能是const。如果键不存在,它将创建一个具有默认值的新条目,以增加地图的大小,该条目将包含一个带有空字符串的新键(在这种情况下,如果键确实存在,则作为值)还不存在。 如前所述,在从地图读取和使用时,应避免使用operator [],以确保进行绑定检查。这是人们经常对地图犯的最常见错误之一。除非您的代码知道这一事实,否则应使用“插入”和“在”。查看有关常见错误Curiously Recurring C++ Bugs at Facebook

的讨论

答案 5 :(得分:0)

虽然有点晚了,但我还是要回答,感谢之前对这个问题的回答,我能够伪造这个重用指针和值的类,它创建两个映射来存储数据,如果有人感兴趣,这里是代码..

adb logcat

使用类:

template<class T1, class T2> class Bimap
{
std::map<T1, T2*> map1;
std::map<T2, T1*> map2;
public:
    void addRow(T1 &t1, T2 &t2){
        map1.insert(make_pair(t1, &t2));
        map2.insert(make_pair(t2, &t1));
    }
    T2* findForward(T1 t1){
        T2* value = map1.find(t1)->second;
        return value;
    }
    T1* findBackward(T2 t2){
        T1* value = map2.find(t2)->first;
        return value;
    }
};