Is end() required to be constant in an STL map/set?

前端 未结 10 512
别跟我提以往
别跟我提以往 2021-02-01 15:00

§23.1.2.8 in the standard states that insertion/deletion operations on a set/map will not invalidate any iterators to those objects (except iterators pointing to a deleted eleme

相关标签:
10条回答
  • 2021-02-01 15:04

    I had a similar question recently, but I was wondering if calling end() to retrieve an iterator for comparison purposes could possibly have race conditions.

    According to the standard, two iterators are considered equivalent if both can be dereferenced and &*a == &*b or if neither can be dereferenced. Finding the bolded statement took a while and is very relevant here.

    Because an std::map::iterator cannot be invalidated unless the element it points to has been removed, you're guaranteed that two iterators returned by end, regardless of what the state of the map was when they were obtained, will always compare to each other as true.

    0 讨论(0)
  • 2021-02-01 15:06

    Assuming that (1) map implemented with red-black tree (2) you use same instance "after a zillion insertions/deletions"- answer "Yes".

    Relative implmentation I can tell that all incarnation of stl I ever know use the tree algorithm.

    0 讨论(0)
  • 2021-02-01 15:07

    C++ Standard states that iterators should stay valid. And it is. Standard clearly states that in 23.1.2/8:

    The insert members shall not affect the validity of iterators and references to the container, and the erase members shall invalidate only iterators and references to the erased elements.

    And in 21.1/7:

    end() returns an iterator which is the past-the-end value for the container.

    So iterators old_end and new_end will be valid. That means that we could get --old_end (call it it1) and --new_end (call it it2) and it will be the-end value iterators (from definition of what end() returns), since iterator of an associative container is of the bidirectional iterator category (according to 23.1.2/6) and according to definition of --r operation (Table 75).

    Now it1 should be equal it2 since it gives the-end value, which is only one (23.1.2/9). Then from 24.1.3 follows that: The condition that a == b implies ++a == ++b. And ++it1 and ++it2 will give old_end and new_end iterators (from definition of ++r operation Table 74). Now we get that old_end and new_end should be equal.

    0 讨论(0)
  • 2021-02-01 15:11

    Well, there's nothing preventing particular collection implementation from having end() depend on the instance of collection and time of day, as long as comparisons and such work. Which means, that, perhaps, end() value may change, but old_end == end() comparison should still yield true. (edit: although after reading the comment from j_random_hacker, I doubt this paragraph itself evaluates to true ;-), not universally — see the discussion below )

    I also doubt you can use std::map<int,Node>::iterator in the Node class due to the type being incomplete, yet (not sure, though).

    Also, since your nodes are uniquely numbered, you can use int for keying them and reserve some value for invalid.

    0 讨论(0)
  • 2021-02-01 15:13

    Iterators in (multi)sets and (multi)maps won't be invalidated in insertions and deletions and thus comparing .end() against previous stored values of .end() will always yield true.

    Take as an example GNU libstdc++ implementation where .end() in maps returns the default intialized value of Rb_tree_node

    From stl_tree.h:

      _M_initialize()
      {
        this->_M_header._M_color = _S_red;
        this->_M_header._M_parent = 0;
        this->_M_header._M_left = &this->_M_header;
        this->_M_header._M_right = &this->_M_header;
      }
    
    0 讨论(0)
  • 2021-02-01 15:20

    23.1/7 says that end() returns an iterator that

    is the past-the-end value for the container.

    First, it confirms that what end() returns is the iterator. Second, it says that the iterator doesn't point to a particular element. Since deletion can only invalidate iterators that point somewhere (to the element being deleted), deletions can't invalidate end().

    0 讨论(0)
提交回复
热议问题