Перегрузка оператора ‹ с константой, но не вставлять в карту как константу

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

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, но я не знаю, как решить эту проблему.


person random    schedule 17.10.2010    source источник


Ответы (1)


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

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


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

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