There is a map of a type std::map<A*, B*> m that describes correspondence between objects of type A and objects of type B. There is a function int exctractInfo(const A *a) that needs to read some info from an object of type B which corresponds to a given object of type A. This is a semantically constant operation, nothing needs to be changed, we just need to read some info, but the problem is that C++ doesn't allow access to map m via a pointer to const.
Consider the following code:
#include <map> class A { }; class B { int info_; public: int info() const { return info_; } }; std::map<A*, B*> m; int exctractInfo(const A *a) { auto it = m.find(a); if (it != m.end() && it->second) { return it->second->info(); } return -1; } int main () { return 0; } Here's a link to online compiler for this code. I get the following error:
error: invalid conversion from 'const A*' to 'std::map::key_type {aka A*}' [-fpermissive]
Now I see two solutions:
Rewrite the type
std::map<A*, B*>asstd::map<const A*, B*>, as I have access to the source code, but that is basically a type of a library object, and a lot of code depend on it, so it will have to be changed, thus changing the map type is really undesirable;Use const cast like this:
auto it = m.find(const_cast<A*>(a));, which also doesn't seem like a good solution, more of a hack.
I don't understand why it doesn't work. If the key is std::string or int, for example, I can access std::map<std::string, B*> via const std::string just fine. So what's wrong with my example? Is there a proper way to handle this situation?
A * constjust fine, but not aA const *. My guess isextractInfocould take aA * constinstead.std::map<A*, B*, std::less<>> m;extractInfo, I'd still have to discard const qualifier at some point. The point is that object A is not allowed to be changed, that's why it's const. But theconst *Aand*Awill hold the same address, so it's the same key, so technically it should be enough the access a value of a map without changing anything along the way.