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
- When I define a class type object const, all members become const as well?
- 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?
- 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?