Оператор перегрузки <с const, но не вставлять в карту как const - PullRequest
0 голосов
/ 17 октября 2010

У меня проблема. У меня есть класс с перегруженным оператором, как это ..

class Foo
{
        friend bool operator<(const Foo &a, const Foo &b);
        ...
};

bool operator<(const Foo &a, const Foo &b)
{
        return a.member < b.member;
}

Затем в функции в классе, которая содержит несколько Foos на карте в качестве ключей ...

void Bar::Update()
{
        for (FooItr itr = foos.begin(); itr != foos.end();) {
                FooItr test = itr++;
                if (!test->first.Check()) { // Check() is const
                        my_map.insert(*test);
                        foos.remove(test);
                }
        }

        for (MapItr itr = my_map.begin(); itr != my_map.end(); ++itr) {
                itr->first.Update(); // Update is not const
        }
}

и я получаю сообщение об ошибке вроде ...

error: passing ‘const Foo’ as ‘this’ argument of ‘void Foo::Update()’ discards qualifiers

Я думаю, причина в том, что my_map.insert () вставляет const Foos, но я не знаю, как решить эту проблему.

1 Ответ

4 голосов
/ 17 октября 2010

Ключи в map всегда const, даже если вы этого не говорите.Это похоже на предотвращение ошибок программирования.

Рассмотрим, что произойдет, если Update изменится member - структура данных карты будет основана на исходном порядке, но теперь, когда member изменился, этот порядокможет быть не так!Карта будет полностью повреждена - вы не сможете правильно найти, вставить или удалить данные.


Итак, некоторые варианты исправить это:

  • Использованиедругая структура данных, где не имеет значения, если объекты «вышли из строя», например, vector.
  • Переместить данные, которые обновляются, в другое место.Иногда он действительно принадлежит во mapped_type (второй параметр шаблона map).Иногда вы можете определить новый struct для хранения текущего mapped_type и данных, которые необходимо изменить.
  • Если вы меняли что-то, что не влияет на наблюдаемое состояние типа, например, кэш,тогда я мог бы предложить сделать измененные элементы данных mutable и сделать соответствующие функции-члены const или сохранить изменяемые данные в scoped_ptr.Однако функция с именем Update предполагает, что обновляемые данные имеют основополагающее значение для типа.
...