我有一个名为map
的{{1}},如下所示:
valueMap
然后我通过引用将这个地图传递给一个函数:
typedef std::map<std::string, std::string>MAP;
MAP valueMap;
...
// Entering data.
如何从地图中获取值,该值作为对函数的引用传递?
答案 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异常。
答案 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”
答案 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;
}
};