1

Possible Duplicate:
C++ STL set update is tedious: I can’t change an element in place

I am stumped:

struct File {
    struct Handle {
         size_t count;
    }; 
    std::set<Handle>::iterator handle_;
    ~File() {
        File::close(*this);
    }
    static void close(File &f) {
        (*f.handle_).count--;
    }
};

With ICC the error is:

error #137: expression must be a modifiable lvalue
(*f.handle_).count++;
^

Why is std::set::iterator const?

Community
  • 1
  • 1
Anycorn
  • 50,217
  • 42
  • 167
  • 261

1 Answers1

3

std::set::iterator is a constant iterator because modifying the value of an element in the set may invalidate the total ordering and uniqueness of elements. To modify an element, you need to copy it out, erase the element, modify your copy and then put it back in the set.

Handle handle = *(f.handle_);
set.erase(f.handle_);
handle++;
set.insert(handle);

// or just set.insert(++handle) if you've overloaded prefix increment too
Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
  • I think this was a mistake by the standards committee. Preferring safety over flexibility and speed has never been the C++ way. There are so many other areas that are just as dangerous, you're just expected to know about them. – Mark Ransom Dec 27 '12 at 23:49
  • This was not a mistake. A set is a "set" because it's ordered and unique. If you could do updates like that then it wouldn't be a set, it would be a different data structure. – bstamour Dec 28 '12 at 00:42
  • `std::not_a_set_for_long` – Joseph Mansfield Dec 28 '12 at 00:48