如何从地图中获取值

How can I get a value from a map?

本文关键字:获取 地图      更新时间:2023-10-16

我有一个名为valueMapmap,如下所示:

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

然后我通过引用将此映射传递给函数:

void function(const MAP &map)
{
  std::string value = map["string"];
  // By doing so I am getting an error.
}

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

std::map::operator[]是一个非常量成员函数,你有一个常量引用。

您需要更改function的签名,或者执行以下操作:

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

operator[]通过将默认构造的值添加到映射并返回对它的引用来处理错误。当您拥有的只是一个常量引用时,这是没有用的,因此您需要做一些不同的事情。

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

如果缺少键,map.at("key")会引发异常。

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

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

主要问题是operator[]用于在映射中插入和读取值,因此它不能是 const.
如果键不存在,它将创建一个带有默认值的新条目,递增映射的大小,该条目将包含一个带有空字符串的新键,在这种情况下,如果键尚不存在,则作为值><。从地图读取时应避免operator[],并使用如前所述map.at(key)以确保绑定检查。这是人们经常使用地图时最常犯的错误之一。你应该使用 insertat,除非你的代码知道这一事实。查看此讨论 常见错误 奇怪的重复出现的 C++ 错误 在 Facebook 上

Steve Jessop的回答很好地解释了为什么你不能在const std::map上使用std::map::operator[]Gabe Rainbow的回答提出了一个不错的选择。我只想提供一些有关如何使用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
未找到键"强">

Ideone上的代码

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

好吧,您可以将其作为参考传递。即标准引用包装器。

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"] );
}

我认为这很好,很简单。享受。。。

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

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;
    }
};

使用类:

//Init mapp with int,int
Bimap<int,int> mapp;
//Add a row(Record) in bimap
int a = 5;
int b = 7002;
mapp.addRow(a, b);
//Print a record
int *ans= mapp.findForward(a);
cout<<"Bimap Returned:"<<*ans<<endl;