从Visual Studio 2010开始,遍历集合似乎会返回一个将数据作为“常量数据”而不是非常量进行解引用的迭代器。当从Visual Studio 2010开始取消引用迭代器时的const引用从Visual Studio 2010开始
下面的代码是一些在Visual Studio 2005上编译但不在2010上的例子(这是一个人为的例子,但清楚地说明了我们在自己的代码中发现的问题)。
在这个例子中,我有一个类与温度一起存储位置。我定义了比较运算符(并非全部,仅足以说明问题),只使用位置而不是温度。重点是对于我来说,如果位置相同,两个实例是相同的;我不在乎温度。
#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个点。
for循环遍历该集合,并设置温度。逻辑上这是允许的,因为比较操作员没有使用温度。
此代码正确编译在Visual Studio 2005,但下面的行给出了Visual Studio 2010的编译错误(在for循环):
DataPoint &point = *it;
给出的错误在于,它无法分配一个“const数据点”指向[非常量]“DataPoint &”。
如果您有比较运算符只比较数据成员的某些部分,那么在VS2010中似乎没有像样的(非肮脏的)代码编写方式。
可能的解决方案是:
- 添加一个常量播到它给出了一个错误
- 进行温度可变的线,使setTemperature一个const方法
但对我来说这两种解决方案看起来相当“脏”。
看起来C++标准委员会忽视了这种情况。或不?
什么是干净的解决方案来解决这个问题? 你们有没有遇到同样的问题,你是如何解决它的?
帕特里克
http://connect.microsoft.com/VisualStudio/feedback/details/532300/std-set-t-iterator-and-std-set-t-const-iterator-are-the-同类型中断码 – mlvljr 2012-05-10 12:43:10
尼斯链接。似乎我不是唯一一个找到它的人。 – Patrick 2012-05-10 14:09:16
是的,我只是写了一些(现在很清楚)错误的STL ::设置代码,经过一小时的调试,这就是谷歌搜索,来到这里和那里:) – mlvljr 2012-05-10 21:11:06