Bezdepbonusu7Программирование: статьи и ответы

Вопрос

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

Автор вопроса: randomОтветов: 1

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

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

c++constantsoperator-overloading

Ответы

Ответ 1 · рейтинг 4 · Doug

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

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


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

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы