C++ Standard: Unexpected const_iterator in multiset

前端 未结 2 1646
执念已碎
执念已碎 2021-01-05 03:10

I recently ran into an odd issue where I\'d get a const_iterator instead of the expected iterator when iterating through a multiset. It turned out

相关标签:
2条回答
  • 2021-01-05 04:08

    The iterators for set and multiset were changed from the standard iterator/const iterator pair to just being const iterators. The reason for this change was that they are ordered containers, and changing the element inside of an iterator can actually invalidate this ordering constraint.

    The version of GCC you're testing against has made this change, the version of VC that you're using has not. VC10 (and VC9 SP1, I believe) always return const_iterators from sets and multisets.

    23.2.4/6 of the latest draft of C++1x (n3000.pdf at the moment) says

    For associative containers where the value type is the same as the key type, both iterator and const_iterator are constant iterators.

    std::set and std::multi_set are the associative containers where the value type is the same as the key type.

    0 讨论(0)
  • 2021-01-05 04:11

    How to fool the compiler for std::set::iterator?

    I have struct

    struct _item {
      int a;
      int b;
      bool operator <(const _item& x) const {return a<x.a;}
    };
    

    I want change only member b (b is irrelevant for sorting in set, only member a is compared).

    std::set<_item> data;
    std::set<_item>::iterator iter=data.begin();
    iter->b=0;  // error !!!
    

    Avada Kedavra !

    struct _item {
      int a;
      int b;
      _item* self;
      _item() {self=this;} 
      bool operator <(const _item& x) const {return a<x.a;}
    };
    iter->self->b=0; // Success !! Tested on VC10
    

    Of course more C + + correctly

    struct _item {
      int a;
      int b;
     private:
      _item* self;
     public:
      _item() {self=this;} 
      bool operator <(const _item& x) const {return a<x.a;}
      int& bReference() const {return self->b;}
    };
    std::set<_item> items;
    std::set<_item>::iterator iter=items.begin();
    iter->bReference()=0; // Success !! Tested on VC1
    
    0 讨论(0)
提交回复
热议问题