【问题标题】:Iterator for set of pairs is const? [duplicate]成对集合的迭代器是 const? [复制]
【发布时间】:2014-08-28 20:52:25
【问题描述】:

我收到以下错误消息:

"表达式必须是可修改的左值iter->first = iter->second;"

代码:

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-&gt;first 似乎被视为 const

【问题讨论】:

标签: c++ iterator constants


【解决方案1】:

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

正如 23.2.4 中所说的

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

【讨论】:

  • 哇,我没有意识到我正在尝试更改密钥...
【解决方案2】:

set&lt;T&gt;::iterator 总是* 一个常量迭代器,就像set&lt;T&gt;::const_iterator,所以你不能用它来修改集合的任何元素。如果您可以直接修改集合的元素,那么集合很可能会变得无序,这只会导致 Bad Things™。

* 好吧,至少从 C++11 开始,尽管在此之前任何主要实现都不太可能有非常量集迭代器。

【讨论】:

  • 我昨天注意到set&lt;T&gt;::begin() 在 VS2008 中返回了一个非常量迭代器。但是,VS2008 是古老的 :)
  • 我过去使用过非常量 set 迭代器,它非常有用。您将对象的一部分设置为键,该键必须保持不变,但您可以随意修改对象的其余部分。看到这个功能消失了,我很难过。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-26
  • 2015-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-12
相关资源
最近更新 更多