Начиная с Visual Studio 2010, итерация по набору, похоже, возвращает итератор, который разыскивает данные как "данные const" вместо не 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);
}
}
В основной процедуре у меня есть набор, к которому я добавляю несколько точек. Чтобы проверить правильность оператора сравнения, я добавляю точки данных с одинаковой позицией несколько раз. При написании содержимого набора я ясно вижу, что в наборе всего 3 точки.
Петли for-loop над множеством и задают температуру. Логически это допускается, так как температура не используется в операторах сравнения.
Этот код правильно компилируется в Visual Studio 2005, но дает ошибки компиляции в Visual Studio 2010 в следующей строке (в цикле for):
DataPoint &point = *it;
Приведенная ошибка заключается в том, что он не может назначить "const DataPoint" для [не const] "DataPoint &".
Кажется, что у вас нет достойного (= не грязного) способа записи этого кода в VS2010, если у вас есть оператор сравнения, который сравнивает только части элементов данных.
Возможные решения:
- Добавление const-cast в строку, где она дает ошибку
- Изменение температуры и создание setTemperature - метод const
Но для меня оба решения кажутся довольно "грязными".
Похоже, что комитет по стандартам С++ упустил эту ситуацию. Или нет?
Каковы чистые решения для решения этой проблемы? Некоторые из вас столкнулись с этой проблемой и как вы ее разрешили?
Патрик