Cornered by const: std::map::find() const overload
Consider the following snippet:
#include <map>
class C {
public:
C() {}
const int& f(const int& x) const
{
// Error: cannot cast const int* to int* const
return myMap.find(&x)->second;
// With a const_cast works:
//return myMap.find(const_cast<int* const>(&x))->second;
}
std::map<int*, int> myMap;
};
int _tmain(int argc, _TCHAR* argv[])
{
int x = 0;
C c;
c.f(x);
return 0;
}
The error in f()
is caused by the const overload of map's find()
taking a const KeyType&
. Because the key type of the map is int*
, this turns in to int* const
. f()
takes a const int&
parameter, which is correct because the parameter is never modified.
Unfortunately this ends up in trying to cast a const int*
to a int* const
, which loses the const qualifier on the int and won't compile.
This is kind of irritating because the parameter definitely isn't ever modified - it's just used for a find() - but I still need to const_cast
it.
Is there a way to write f()
without the const_cast
?
You can just change the type of the map
to std::map<const int*, int>
; I question whether you need pointers as keys in the first place, though. As James points out, the key type should be const int*
because you never intend to modify the referent via the map
. If you did, I'd be even more worried.
The real question is: why isn't the index of the map a pointer
to const? (Supposing, of course, that it should be a pointer.)
Do you really want to be able to modify the index via something
like *myMap.find(&x)->first = xxx
; I would say that that is
quite unusual, given that you already have a pointer to the
object.
精彩评论