2010-01-10 46 views
7

我最近遇到了一个奇怪的问题,我在迭代multiset时得到了const_iterator而不是预期的iterator。它原来是一个非问题的MSVC但G ++给了我一个错误:C++标准:multiset中意外的const_iterator

error: invalid initialization of reference of type 'myPtr&' from expression of type 'const boost::shared_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是否偏离定义良好的标准。

在此先感谢。

+0

改变 '我的' 的DECL到'常量myPtr&mine'。当然,'tick'必须声明为'void tick(float)const;'并且由tick修改的任何数据成员都需要是'mutable'。 – KitsuneYMG 2010-01-10 21:18:04

回答

15

将set和multiset的迭代器从标准iterator/const迭代器对更改为仅仅是const迭代器。这种改变的原因是它们是有序的容器,并且改变迭代器中的元素实际上可以使这种排序约束失效。

您正在测试的GCC版本已做出此更改,您正在使用的VC版本尚未进行此更改。我相信VC10(和VC9 SP1)总是从集合和多集合中返回const_iterator。

23.2.4/C++ 1X(目前n3000.pdf)的最新草案6说

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

的std ::设置和std :: multi_set是关联容器,其中值类型与密钥类型相同。

+0

太棒了!我刚刚测试了VC10b2,确实发生了同样的错误。现在,如果我只明白标准的哪一部分准确定义了这一点。 – Svenstaro 2010-01-11 02:22:24

+0

C++ 1x最新草案的23.2.4/6说“对于值类型与键类型相同的关联容器,iterator和const_iterator都是常量迭代器。” std :: set和std :: multi_set是值类型与键类型相同的关联容器。 – 2010-01-11 02:34:06

1

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

我已经STRUCT

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

我想仅改变构件B(B是不相关的用于集合排序,只有一个构件相比较)。

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 
+1

他希望ABT标准的信息,而不是一个解决办法 – owagh 2012-11-29 20:40:37

+0

或者你可以使用'const_cast'。顺便说一句,如果元素被复制或分配,您的解决方案将失败。 – immibis 2015-10-05 09:15:02