首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在set上取消迭代器时的Const引用,从Visual 2010开始

在set上取消迭代器时的Const引用,从Visual 2010开始
EN

Stack Overflow用户
提问于 2010-03-26 12:19:44
回答 3查看 8K关注 0票数 11

从Visual 2010开始,对一个集合进行迭代似乎返回了一个迭代器,该迭代器将数据解压缩为“const数据”,而不是非const数据。

下面的代码是在Visual 2005上编译的代码示例,但不是在2010年编译的代码(这是一个人为的示例,但清楚地说明了我们在自己的代码中发现的问题)。

在这个例子中,我有一个类,它存储一个位置和一个温度。我定义了只使用位置而不是温度的比较运算符(并不是所有的比较运算符,都足以说明问题)。问题是,对于我来说,如果位置相同的话,两个例子是相同的;我不在乎温度。

代码语言:javascript
复制
#include <set>

class DataPoint
   {
   public:
      DataPoint (int x, int y) : m_x(x), m_y(y), m_temperature(0) {}
      void setTemperature(double t) {m_temperature = t;}
      bool operator<(const DataPoint& rhs) const
         {
         if (m_x==rhs.m_x) return m_y<rhs.m_y;
         else              return m_x<rhs.m_x;
         }
      bool operator==(const DataPoint& rhs) const
         {
         if (m_x!=rhs.m_x) return false;
         if (m_y!=rhs.m_y) return false;
         return true;
         }
   private:
      int m_x;
      int m_y;
      double m_temperature;
   };

typedef std::set<DataPoint> DataPointCollection;

void main(void)
{
DataPointCollection points;

points.insert (DataPoint(1,1));
points.insert (DataPoint(1,1));
points.insert (DataPoint(1,2));
points.insert (DataPoint(1,3));
points.insert (DataPoint(1,1));

for (DataPointCollection::iterator it=points.begin();it!=points.end();++it)
   {
   DataPoint &point = *it;
   point.setTemperature(10);
   }
}

在主例程中,我有一个集合,我在其中添加了一些要点。为了检查比较操作符的正确性,我多次添加相同位置的数据点。在写集的内容时,我可以清楚地看到在集合中只有3点。

反循环在集合上循环,并设置温度.从逻辑上讲,这是允许的,因为温度不是在比较操作符中使用。

此代码在Visual 2005中正确编译,但在以下行(for-循环中)给出Visual 2010中的编译错误:

代码语言:javascript
复制
   DataPoint &point = *it;

给出的错误是,它不能将"const DataPoint“分配给非const "DataPoint &”。

如果您有一个只比较部分数据成员的比较运算符,那么您似乎没有合适的(=非脏的)方法在VS2010中编写这段代码。

可能的解决办法是:

  • 向行中添加了一个const-cast,其中它给出了一个错误
  • ,使温度可变,并使setTemperature成为const方法

但在我看来,这两种解决方案都相当“肮脏”。

看起来,C++标准委员会忽视了这种情况。还是不想?

解决这个问题的清洁解决方案是什么?你们中的一些人遇到过同样的问题吗?你们是如何解决的?

帕特里克

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-03-26 12:25:49

迭代器应该给您一个const引用(这是标准要求它应该做的),因为更改引用的内容会破坏集合的底层数据结构的有效性-- set并不“知道”您正在更改的字段实际上不是键的一部分。替代方法是通过删除和重新添加来进行更改,或者使用std::map代替。

票数 13
EN

Stack Overflow用户

发布于 2010-09-22 13:57:40

就在最近,我们开始转向2010年,这是我们一直面临的最大障碍。幸运的是,他们确实揭示了一些长期存在的问题,我们改变了构成这组序列的部分内容。

在其他情况下,我们的解决方案是使用可变方法并将方法声明为const。当通过引用(指针或引用)将取消引用的迭代器传递给函数时,如果参数没有被更改,我们就会同意参数。

丹尼斯

票数 1
EN

Stack Overflow用户

发布于 2010-03-28 22:54:08

Set应该返回一个const迭代器,因为它不知道是否有任何成员函数可以更改排序。

看起来你真的想要一张地图,在那里你把你的不变的(x,y)键映射到一个可变的温度。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2523139

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档