Error: passing X as 'this' argument discards qualifiers

137 Views Asked by At

Turns out I don't really understand const.. So I have this (minimized) code sample. When I try to call a function which has access to members of a const class object (-> GetData()) I get the following error:

Error (gcc 11.2):

<source>:129:28: error: passing 'const std::unordered_map<int, A>' as 'this' argument discards qualifiers [-fpermissive]
  129 |         return some_data_[0];
      |                            ^
In file included from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/unordered_map:47,
                 from <source>:103:
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/unordered_map.h:983:7: note:   in call to 'std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::mapped_type& std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator[](std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::key_type&&) [with _Key = int; _Tp = A; _Hash = std::hash<int>; _Pred = std::equal_to<int>; _Alloc = std::allocator<std::pair<const int, A> >; std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::mapped_type = A; std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::key_type = int]'
  983 |       operator[](key_type&& __k)
      |       ^~~~~~~~

Code:

#include <unordered_map>

class A
{

public:

    A() : cnt_(0) {}
    A(int cnt) : cnt_(cnt) {}

    int& GetCnt() {
        return cnt_;
    };

private:
    int cnt_;
};

class B
{
public:
    B(int nr) {
        some_data_ = { { 0, A(nr) } };
    }

    const A& GetData() const {
        return some_data_[0];
    }

private:
    std::unordered_map<int, A> some_data_;
};

int main()
{
    const B b_obj(2);

    b_obj.GetData();
}

Do I understand correctly that

  1. When I define a class type object const, all members become const as well?
  2. All members const means also that somehow this constness translates to unoredered_map-contents being const? If so, how? Is there some template magic behind it to add the qualifier?
  3. If the above assumptions are correct, how else than through a const X const function do I pass read-only access to members of the const class (map value in this case) to an outside function?
0

There are 0 best solutions below