2014-08-28 70 views
0

我收到以下错误消息:“表达式必须是可修改的左值iter-> first = iter-> second;”代码:对的集合的迭代器是const?

func(const std::set<Edge> &obstructEdges1, 
     const std::set<Edge> &obstructEdges2) 
{ 
std::set<Edge> obstructEdges = obstructEdges1; 
obstructEdges.insert(obstructEdges2.begin(), obstructEdges2.end()); 

for (std::set<Edge>::iterator iter = obstructEdges.begin(); 
    iter != obstructEdges.end(); iter++) 
{ 
    if (iter->first > iter->second) 
    { 
    int t = iter->first; 
    iter->first = iter->second; 
    iter->second = t; 
    } 
... 

Edge是一对整数。怎么了?由于某种原因,看起来像iter->first被认为是const

+0

@ juanchopanza我将常量集合复制到非常量集合中。 – 2014-08-28 20:53:53

+1

相似的(在AndreyT的答案后发现):http://stackoverflow.com/questions/4064841/strange-error-setintbegin-always-returning-const-iterator – 2014-08-28 20:58:00

回答

4

是,std::set迭代器始终是一个常量迭代即使该组本身不是const,即std::set::iteratorstd::set::const_iterator都是恒定迭代器(并且可以指的是相同的类型)。请注意,std::set是一个关联容器。在标准关联容器中,您不允许修改已存储的密钥,这意味着您在std::set中不允许修改任何内容。当然,你的比较器不必将整个集合元素当作关键字,但从整个角度来看,整个事物是关键,因此是不可变的。

,因为它说在23.2.4

迭代关联容器的是双向迭代类。对于值类型为 与关键字类型相同的关联容器,iterator和const_iterator都是 常量迭代器。未指定迭代器和const_iterator是否是相同的类型。

+0

哇,我没有意识到我想改变关键。 .. – 2014-08-28 20:58:50

4

set<T>::iterator始终*恒定的迭代器,就像set<T>::const_iterator,所以你不能用它来修改设定的任何元素。如果你可以直接修改这个集合的元素,那么这个集合很可能变成无序的,这只会导致Bad Things™。

*好吧,至少从C++ 11开始,尽管至少在任何主要实现中都不可能有很长的非const集迭代器。

+0

我昨天注意到'set :: begin()'在VS2008中返回一个非const迭代器。但是,VS2008是古老的:) – 2014-08-28 21:00:02

+0

我在过去使用过非const的'set'迭代器,它非常有用。您将对象的一部分设置为密钥,必须保持不变,但您可以随意修改对象的其余部分。我很难过看到该功能消失。 – 2014-08-28 22:10:26