How can I get a value from a map?
Solution 1:
std::map::operator[]
is a non-const member function, and you have a const reference.
You either need to change the signature of function
or do:
MAP::const_iterator pos = map.find("string");
if (pos == map.end()) {
//handle the error
} else {
std::string value = pos->second;
...
}
operator[]
handles the error by adding a default-constructed value to the map and returning a reference to it. This is no use when all you have is a const reference, so you will need to do something different.
You could ignore the possibility and write string value = map.find("string")->second;
, if your program logic somehow guarantees that "string"
is already a key. The obvious problem is that if you're wrong then you get undefined behavior.
Solution 2:
map.at("key")
throws exception if missing key.
If k does not match the key of any element in the container, the function throws an out_of_range exception.
http://www.cplusplus.com/reference/map/map/at/
Solution 3:
The answer by Steve Jessop explains well, why you can't use std::map::operator[]
on a const std::map
. Gabe Rainbow's answer suggests a nice alternative. I'd just like to provide some example code on how to use map::at()
. So, here is an enhanced example of your 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.
}
}
And here is an example main()
function:
int main() {
MAP valueMap;
valueMap["string"] = "abc";
function(valueMap, "string");
function(valueMap, "strong");
return 0;
}
Output:
Value of key "string": abc
Key "strong" not found
Code on Ideone
Solution 4:
The main problem is that operator[]
is used to insert and read a value into and from the map, so it cannot be const.
If the key does not exist, it will create a new entry with a default value in it, incrementing the size of the map, that will contain a new key with an empty string ,in this particular case, as a value if the key does not exist yet.
You should avoid operator[]
when reading from a map and use, as was mention before, map.at(key)
to ensure bound checking. This is one of the most common mistakes people often do with maps. You should use insert
and at
unless your code is aware of this fact. Check this talk about common bugs Curiously Recurring C++ Bugs at Facebook