Начиная с 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" [non-const] "DataPoint &".
Похоже, у вас нет приличного(= не грязный) способ написания этого кода в VS2010, если у вас есть оператор сравнения, который сравнивает только части элементов данных.
Возможные решения:
- Добавление const-передача на строку, где она выдает ошибку
- Создание изменяемой температуры и установка setTempera по постоянному методу
Но мне оба решения кажутся довольно «грязными».
Похоже, комитет по стандартам C ++ упустил из виду эту ситуацию.Или нет?
Какие есть чистые решения для решения этой проблемы?Кто-нибудь из вас сталкивался с такой же проблемой и как вы ее решили?
Патрик