1
votes

Why is that I cannot get the value of a key, in a const ref unordered_map that I have passed into the function, but I can for a local unordered_map ?

GameObject(const std::unordered_map<int,std::unordered_map<int,int>>& objectParameters){
        if (objectParameters.find(CAPABILITY_TYPE_SPECIE)!=objectParameters.end()) {

 //Following line gives an error:
    auto map2 = objectParameters[CAPABILITY_TYPE_SPECIE];         

//Following line works just fine
            std::unordered_map<int,std::unordered_map<int,int>> objectParameters2;
            auto map = objectParameters2[CAPABILITY_TYPE_SPECIE];

        }

Why can't I get the value from objectParameters ? The error that the compiler complains is:

No viable overloaded operator[] for type 'const std::unordered_map >'

EDIT: Removing "const" from the type seems to make the error go away. Why is that ?

2
map::at() is the member function you need. auto map2 = objectParameters.at(CAPABILITY_TYPE_SPECIE);. Please look at Killzone Kid's answer!Andreas H.

2 Answers

3
votes

operator[] is a non-const member function and can't be called on an object you have by a const reference. It can't be a const member, since it's specified to insert an item if the key isn't in the map. And it just so happens you don't even need to use it.

You employ find() and then just discard the result, why? It gets an iterator to the item if that item exists. So don't discard it, use it.

auto item = objectParameters.find(CAPABILITY_TYPE_SPECIE);
if (item != objectParameters.end()) {
     auto map2 = item->second;

Though if you want map2 to be the same one that is already in map1, the above doesn't do that either. Since auto map2 is a copy of item->second. To modify the item in map1, we'd need to make map2 a reference:

auto item = objectParameters.find(CAPABILITY_TYPE_SPECIE);
if (item != objectParameters.end()) {
     auto& map2 = item->second;

Regarding your edit, removing const to "fix" such errors is the wrong thing to do. Const correctness is important, and when you do such a "fix" it can introduce subtle bugs into your code. Because now things that shouldn't change may start changing unexpectedly.

2
votes

Why can't I get the value from objectParameters ?

Because when accessing map element with operator [] and key doesn't exist it will be created. Obviously compiler cannot do this if map is const.

You could try using .at() as it has const overload http://en.cppreference.com/w/cpp/container/map/at