How to operator[] access element in a const map in C++?

Posted on

How to operator[] access element in a const map in C++? For example, the compiler will report error on this piece of code:

#include <iostream>
#include <string>
#include <map>

std::int64_t count(const std::map<std::string, std::int64_t>& map)
{
  return map["one"] + map["two"];
}

int main ()
{

  std::map<std::string, std::int64_t> map = {
    {"one", 1},
    {"two", 2}
  };

  std::cout << count(map) << std::endl;

  return 0;
}

g++, using command

$ g++ --std=c++11 main.cc -o a

will report

main.cc: In function ‘int64_t count(const std::map<std::basic_string<char>, long int>&)’:
main.cc:7:19: error: passing ‘const std::map<std::basic_string<char>, long int>’ as ‘this’ argument of ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](std::map<_Key, _Tp, _Compare, _Alloc>::key_type&&) [with _Key = std::basic_string<char>; _Tp = long int; _Compare = std::less<std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, long int> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = long int; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::basic_string<char>]’ discards qualifiers [-fpermissive]
   return map["one"] + map["two"];
                   ^
main.cc:7:32: error: passing ‘const std::map<std::basic_string<char>, long int>’ as ‘this’ argument of ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](std::map<_Key, _Tp, _Compare, _Alloc>::key_type&&) [with _Key = std::basic_string<char>; _Tp = long int; _Compare = std::less<std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, long int> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = long int; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::basic_string<char>]’ discards qualifiers [-fpermissive]
   return map["one"] + map["two"];
                                ^

To access the data of a const map in C++, use the at() member function,

const mapped_type & at (const key_type &__k) const 

instead of operator[]. The reason why operator[] can not be used for a const map is because that, if the key from operator[] does not exist, a pair with that key is created using default values and then returned, which will actually change the map.

Note that at() may throw std::out_of_range exception if no such data is present.

For the code in the question, to make it work, change

std::int64_t count(const std::map<std::string, std::int64_t>& map)
{
  return map["one"] + map["two"];
}

to

std::int64_t count(const std::map<std::string, std::int64_t>& map)
{
  return map.at("one") + map.at("two");
}

Eric Ma

Eric is a systems guy. Eric is interested in building high-performance and scalable distributed systems and related technologies. The views or opinions expressed here are solely Eric's own and do not necessarily represent those of any third parties.

One comment

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Posts