Pat*_*ick 11 c++ iterator visual-studio-2010 c++11
从Visual Studio 2010开始,迭代一个集合似乎返回一个迭代器,它将数据解引用为'const data'而不是non-const.
下面的代码是在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);
}
}
Run Code Online (Sandbox Code Playgroud)
在主程序中,我有一个集合,我添加了一些点.为了检查比较运算符的正确性,我多次添加具有相同位置的数据点.在写集合的内容时,我可以清楚地看到集合中只有3个点.
for循环在集合上循环,并设置温度.逻辑上这是允许的,因为温度不用于比较运算符.
此代码在Visual Studio 2005中正确编译,但在Visual Studio 2010中的以下行(在for循环中)中提供了编译错误:
DataPoint &point = *it;
Run Code Online (Sandbox Code Playgroud)
给出的错误是它不能将"const DataPoint"分配给[non-const]"DataPoint&".
如果你有一个只比较部分数据成员的比较运算符,你似乎没有像在VS2010中编写这段代码的方法(=非脏).
可能的解决方案是
但对我来说,这两种解决方案看起来都很"脏".
看起来C++标准委员会忽略了这种情况.或不?
什么是解决这个问题的清洁解决方案?你们有些人遇到同样的问题,你是如何解决的?
帕特里克
小智 13
迭代器应该给你一个const引用(这就是标准所说它应该做的),因为更改引用的东西会破坏集合的底层数据结构的有效性 - 集合不会"知道"你所在的字段改变实际上并不是关键的一部分.替代方法是通过删除和重新添加来进行更改,或者使用std :: map来进行更改.
归档时间: |
|
查看次数: |
7855 次 |
最近记录: |