0

I have a 2 by 3 set<set<int> > named ss like this:

5 6 7
6 7 8

and I want to remove all 6's in it and end up like this:

5 7
7 8

I'm trying to do:

for (set<set<int> >::iterator it = ss.begin(); it != ss.end(); it++) {
    it->erase(6);
}

which gives me an error:

error: passing ‘const std::set<int>’ as ‘this’ argument of ‘std::set<_Key, _Compare, _Alloc>::size_type std::set<_Key, _Compare, _Alloc>::erase(const key_type&) [with _Key = int, _Compare = std::less<int>, _Alloc = std::allocator<int>, std::set<_Key, _Compare, _Alloc>::size_type = long unsigned int, std::set<_Key, _Compare, _Alloc>::key_type = int]’ discards qualifiers [-fpermissive]

I can compile it by passing -fpermissive and it seems to be working fine but I was wondering what this error is all about.

EDIT after hyde's suggestion I tried:

for (set<set<int> >::iterator it = ss.begin(); it != ss.end(); it++) {
    set<int> temp(*it);
    temp.erase(6);
    ss.erase(*it);
    ss.insert(temp);
}

which seems to be working so I'm guessing sets doesn't allow changing elements as he said..

none
  • 11,793
  • 9
  • 51
  • 87
  • maybe a set is not the datastructure you need. What are you trying to achieve in the first place? – moooeeeep Oct 21 '12 at 12:28
  • Is this your real code? Your compiler is complaining that `it` points to a constant set. – alestanis Oct 21 '12 at 12:29
  • @alestanis this is a simplified version of my code but I'm getting the same error in my original code as well.. – none Oct 21 '12 at 12:30
  • @moooeeeep I'm literally trying to eliminate all `6`'s in a 2d set. set makes much more sense than vectors as it's part of an sat solver.. – none Oct 21 '12 at 12:31
  • I meant: you don't have any `const`s in your real code? – alestanis Oct 21 '12 at 12:33
  • @alestanis well I didn't actually, but I have tried putting `const`s in my example and it still gives me the same error. – none Oct 21 '12 at 12:37
  • Does STL set really allow changing the items in the set? I mean, conceptually it is same as removing the existing item and inserting a new different one. Maybe you need to do it this way in your code, if inner set has item, remove the set, remove the item, put the new set back to outer set. – hyde Oct 21 '12 at 12:41
  • @hyde see the edit. you can put that as an answer so I can accept, thanks.. – none Oct 21 '12 at 12:53
  • @gokcehan Added an answer. A note about your edited question as it is now: You remove the inner set and put it back even if there was no change. It would be better to test first if any change is going to happen, before doing all the copying, removing and inserting. – hyde Oct 21 '12 at 14:56

2 Answers2

1

You are trying to change key which is not allowed

  • Are you sure about that? It **is** allowed. – alestanis Oct 21 '12 at 12:35
  • I mean this: http://stackoverflow.com/questions/908949/what-happens-when-you-modify-an-element-of-an-stdset and this http://stackoverflow.com/questions/2217878/c-stl-set-update-is-tedious-i-cant-change-an-element-in-place –  Oct 21 '12 at 12:41
  • I have just tried creating a temporary 2d set from the original one and iterate over it while also finding the iterator value from the original one and then do the remove over it. still got the same error.. – none Oct 21 '12 at 12:43
  • But this shouldn't be a problem with `erase` because you don't screw up the sorting – alestanis Oct 21 '12 at 12:48
  • Oh I got it, the error comes from the big set of sets, not from the inner sets... – alestanis Oct 21 '12 at 12:49
  • @Cheersandhth.-Alf it's not about changing keys, it's about changing an element of a set. – none Oct 21 '12 at 12:59
  • @gokchan: since when did elements of a set become not keys – Cheers and hth. - Alf Oct 21 '12 at 13:00
  • `Sets are a kind of associative container that stores unique elements, and in which the elements themselves are the keys.` http://www.cplusplus.com/reference/stl/set/ –  Oct 21 '12 at 13:01
1

As per comment above, solution: Do not change items in the set, changing item in a set is conceptually same as removing element and inserting a new element. So solution is to

  • iterate outer set
    • check if inner set has the unwanted item
      • remove that inner set
      • remove the unwanted item from removed inner set
      • add the modified inner set back to outer set
hyde
  • 60,639
  • 21
  • 115
  • 176
  • I have already marked skwllsp's answer as accepted and it's also the correct answer and all but this one is much cleaner and helped me to find the solution, thanks again.. checking before changing sounds like a good idea as well, I will give it a try. – none Oct 21 '12 at 15:18
  • @gokcehan yeah, I saw that before writing this answer, so no prob about the accept. – hyde Oct 21 '12 at 15:29