1

I work with polinoms and keep them in std::map as degrees and coefficients. Here's the code pieces:

std::map<int,int> pol;

Map is filled with data and then I begin to process it.

for(std::map<int,int>::iterator it = pol.begin(); it != pol.end(); it++) {
              if( it->first != 0 ) {
                      it->second *= it->first;
                      it->first--;
              }
              else {
                       it->first = 0;
                       it->second = 0;
              }
}

And beginning from it->first-- and further I'm getting very big amount of output with errors like error: decrement of read-only member ‘std::pair<const int, int>::first’ it->first--; ^~ or error: assignment of read-only member ‘std::pair<const int, int>::first’ it->first = it->first - 1; Why is it readonly? How can I fix it?

$ g++ --version
g++ (Debian 6.3.0-5) 6.3.0 20170124
kekyc
  • 317
  • 6
  • 15
  • Possible duplicate of [force key type of a std::map not to be const](http://stackoverflow.com/questions/6773734/force-key-type-of-a-stdmap-not-to-be-const) – nwp Feb 10 '17 at 00:46

1 Answers1

8

It's read-only because if you were allowed to freely modify the key in the map, you would violate the invariant of the data structure the map uses (typically a red-black tree).

You need to remove the element and add it back in with the decremented value. This ensures that the node will be in the correct place in the tree.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • Is there no way to modify the value (not the key) in-place? – synchronizer Feb 10 '17 at 00:46
  • 3
    @synchronizer no there is not; and if you need to do that it means that `map` is not the right data structure for your application – M.M Feb 10 '17 at 00:47
  • How then would you create a simple word frequency dictionary. I am pretty sure that I've done this.... I will check. EDIT: Counter-example? http://stackoverflow.com/questions/4527686/how-to-update-stdmap-after-using-the-find-method – synchronizer Feb 10 '17 at 00:48
  • @synchronizer because you would be modifying the value *associated* with the key, which in this case is `it->second`, not `it->first`. – Austin Brunkhorst Feb 10 '17 at 00:49
  • That is what I was asking. I apologize for the confusion--I was using the Python/Java notion of a Key, Value pair, but in C++ you refer to Key as "first" and the Value as "second". I meant the value of the "Value." – synchronizer Feb 10 '17 at 00:50
  • 1
    @synchronizer You can modify the value, just not the key. If you wanted to make a word frequency dictionary a simple `std::map` will do. You cannot change the `std::string`, but you *can* change the `int`. – nwp Feb 10 '17 at 00:51
  • @Brian Thank you. So I should create a new `std::pair` and then do something like `map.erase(it)` and then `map.insert(it, mypair)` ? – kekyc Feb 10 '17 at 00:51
  • @kekyc No you can't use the erased iterator as a hint to a subsequent insertion since that iterator becomes invalid. But yes insert a new pair, or just use the `[]` syntax. – Brian Bi Feb 10 '17 at 00:55
  • If you wanted to change a word for some reason you would do `map["new word"] = map["old word"]; map.erase["old word"];`. No need to mess with iterators here. – nwp Feb 10 '17 at 00:56