James Franco
James Franco

Reputation: 4706

Why does the following not work when the map is const static

Consider the following example:

enum class DOG_TYPE {SHEPHARD, COLLIE,UNKNOWN};

static  const std::map<std::string,DOG_TYPE> dogMap = {
                {"GS",DOG_TYPE::SHEPHARD}
};


DOG_TYPE getDogType(const std::string& dogtype) 
{
    if(dogMap.find(dogtype) != dogMap.end())
    {
        return  dogMap[dogtype];  -->Does not work when std::map is constant
    }
}

int main()
{
DOG_TYPE j = getDogType("GS");
std::cout << int(j);
}

In the above example the statement return dogMap[dogtype]; returns the error

error: passing 'const std::map<std::__cxx11::basic_string<char>, DOG_TYPE>' as 'this' argument discards qualifiers [-fpermissive]
         return  dogMap[dogtype];

I would like to know why this happens and why cant map be const static ?

Upvotes: 1

Views: 193

Answers (3)

max66
max66

Reputation: 66200

As said by other, operator[] modify the map if the key isn't present.

But you can use at()

DOG_TYPE getDogType(const std::string& dogtype) 
{
    if(dogMap.find(dogtype) != dogMap.end())
    {
        return  dogMap.at(dogtype);
    }
}

And, if you can afford that getDogType() throws an exception when dogtype isn't a key in dogMap, simply

DOG_TYPE getDogType(const std::string& dogtype) 
{
        return  dogMap.at(dogtype);
}

p.s.: at() available only from C++11

p.s.2: sorry for my bad English.

Upvotes: 1

Remy Lebeau
Remy Lebeau

Reputation: 595827

It doesn't work because std::map does not have an operator[] that is declared as const, so you can't use operator[] on a const std::map object.

std::map::operator[] is defined to return a reference to a keyed value. If the key is not found, the map is modified to insert a default value for the key so it can then bind the returned reference. Obviously, modifying a const std::map cannot work, hence the compiler error.

To do what you are attempting, you can use std::map::find() to search for the key without inserting a new value for it. If the key is found, you can dereference the returned iterator.

Don't forget to have your function return a default value if the key is not found.

Try this:

DOG_TYPE getDogType(const std::string &dogtype) 
{
    auto iter = dogMap.find(dogtype);
    if (iter != dogMap.end())
        return iter->second;
    return DOG_TYPE::UNKNOWN;
}

Upvotes: 5

David Schwartz
David Schwartz

Reputation: 182763

Using operator[] on a std::map creates the object if it doesn't exist. So it's an operation that can only be performed on a map you are allowed to modify. Use find instead.

Upvotes: 7

Related Questions