Consider this program:
#include <map>
#include <vector>
typedef std::vector<int> IntVector;
typedef std::map<IntVector,double> Map;
void foo(Map& m,const IntVector& v)
{
Map::iterator i = m.find(v);
i->first.push_back(10);
};
int main()
{
Map m;
IntVector v(10,10);
foo(m,v);
return 0;
}
Using g++ 4.4.0, I get his compilation error:
test.cpp: In function 'void foo(Map&, const IntVector&)':
test.cpp:8: error: passing 'const std::vector<int, std::allocator<int> >' as 'this' argument of 'void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = int, _Alloc = std::allocator<int>]' discards qualifiers
I would expect this error if I was using Map::const_iterator inside foo but not using a non-const iterator.
What am I missing, why do I get this error?
The keys in a map are constant. A map is a tree, and you can’t just going around changing the keys or you’ll break its invariants. The
value_typeof a map withKeyandValueisstd::pair<const Key, Value>, to enforce this.Your design needs some changing. If you really need to modify the key, you need to remove the element, change its key, and re-insert it with the new key.
Also concerning your example specifically, you will get undefined behavior (if this did work). Your map is empty when you call
foo, so the iterator returned byfindwill bem.end(); the element doesn’t exist. But then you’d go on to modify this non-existent element: ka-boom. Whenever youfindsomething, you should check that it was found before you attempt to use it.