代码之家  ›  专栏  ›  技术社区  ›  svenstaro

C++标准:多集中的意外常数迭代器

  •  8
  • svenstaro  · 技术社区  · 15 年前

    我最近遇到了一个奇怪的问题 const_iterator 而不是预期的 iterator 当遍历多集时。这对MSVC来说不是问题,但G++给了我一个错误:

    错误:的初始化无效 “myptr&”类型的引用来自 “const”类型的表达式 Boost::共享\u ptr'

    相关代码:

    typedef std::multiset<myPtr> myList;
    myList _mystuff;
    void tick(float dt)
    {
        for (myList::iterator i = _mystuff.begin(); i != _mystuff.end(); ++i)
        {
            myPtr &mine = *i; // g++ problem here, not for MSVC
            // const myPtr &mine = *i; works fine for g++
            mine->tick(dt);
        }
    }
    

    相当多的研究表明,这是许多以前讨论的一个问题。我发现了这些相关的信息:

    我的背景知识和对这个问题的理解是有限的,因此我想知道标准是否没有很好地定义这个行为,在这种情况下,G++和MSVC实现了他们喜欢的行为,或者G++或MSVC是否偏离了定义良好的标准。

    事先谢谢。

    2 回复  |  直到 13 年前
        1
  •  16
  •   Terry Mahaffey    15 年前

    集合和多集合的迭代器已从标准迭代器/常量迭代器对更改为仅为常量迭代器。这种更改的原因是它们是有序的容器,而更改迭代器内的元素实际上会使这个排序约束失效。

    你测试的gcc版本做了这个修改,你使用的vc版本没有。VC10(和VC9SP1,我相信)总是从集合和多集合返回const_迭代器。

    23.2.4/6的最新草案的C++1X(N300 0.PDF目前)说

    对于关联容器, 值类型与键相同 类型,迭代器和常量迭代器 是常量迭代器。

    std::set和std::multi_set是值类型与键类型相同的关联容器。

        2
  •  1
  •   FrantiÅ¡ek Novotný    13 年前

    如何愚弄std::set::iterator的编译器?

    我有结构

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

    我只想更改成员B(B与集合中的排序无关,只比较成员A)。

    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
    

    当然更多C++

    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