Const map element access

C++DictionaryStlConstants

C++ Problem Overview


I tried to use the operator[] access the element in a const map, but this method failed. I also tried to use at() to do the same thing. It worked this time. However, I could not find any reference about using at() to access element in a const map. Is at() a newly added function in map? Where can I find more info about this? Thank you very much!

An example could be the following:

#include <iostream>
#include <map>

using namespace std;

int main()
{
        map<int, char> A;
        A[1] = 'b';
        A[3] = 'c';

        const map<int, char> B = A;

        cout << B.at(3) << endl; // it works
        cout << B[3] << endl;  // it does not work

}

For using "B[3]", it returned the following errors during compiling:

> t01.cpp:14: error: passing ‘const > std::map, > std::allocator char> > >’ as ‘this’ argument of ‘_Tp& > std::map<_Key, _Tp, _Compare, > _Alloc>::operator[](const _Key&) [with _Key = int, _Tp = char, _Compare = std::less, _Alloc = > std::allocator char> >]’ discards qualifiers

The compiler used is g++ 4.2.1

C++ Solutions


Solution 1 - C++

at() is a new method for std::map in C++11.

Rather than insert a new default constructed element as operator[] does if an element with the given key does not exist, it throws a std::out_of_range exception. (This is similar to the behaviour of at() for deque and vector.)

Because of this behaviour it makes sense for there to be a const overload of at(), unlike operator[] which always has the potential to change the map.

Solution 2 - C++

If an element doesn’t exist in a map, the operator [] will add it – which obviously cannot work in a const map so C++ does not define a const version of the operator. This is a nice example of the compiler’s type checker preventing a potential runtime error.

In your case, you need to use find instead which will only return an (iterator to the) element if it exists, it will never modify the map. If an item doesn’t exist, it returns an iterator to the map’s end().

at doesn’t exist and shouldn’t even compile. Perhaps this is a “compiler extension” (= a bug new in C++0x).

Solution 3 - C++

The []-operator will create a new entry in the map if the given key does not exists. It may thus change the map.

See this link.

Solution 4 - C++

This comes as quite a surprise to me, but the STL map doesn't have a const index operator. That is, B[3] cannot be read-only. From the manual:

http://www.sgi.com/tech/stl/Map.html">Since operator[] might insert a new element into the map, it can't possibly be a const member function.

I have no idea about at().

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionicephereView Question on Stackoverflow
Solution 1 - C++CB BaileyView Answer on Stackoverflow
Solution 2 - C++Konrad RudolphView Answer on Stackoverflow
Solution 3 - C++vidstigeView Answer on Stackoverflow
Solution 4 - C++BetaView Answer on Stackoverflow