2010-09-03 2 views
0

У меня есть мультимножество с пользовательской функцией предиката, например multiset<MyClass *,MyCompFunc>, где MyCompFunc просматривает атрибут объектов MyClass. Во время выполнения приложения объекты могут меняться так, чтобы они были переупорядочены.Убедитесь, что multiset переупорядочивается при изменении объектов

Каков правильный способ заставить мультимножество переупорядочиваться, когда это произойдет? Вручную сортировать его или удалить измененный объект, обновить его и снова вставить?

+0

Обычно я удаляю его и снова вставляю, но я просто собираюсь поставить это как комментарий вместо ответа, потому что я уверен, что есть лучший способ. –

+0

Я уверен, что вам нужно удалить объект, который должен быть изменен, а затем изменить его, а затем снова вставить. Но сейчас я не могу найти ссылку в спецификации C++, которая говорит, что вы не можете изменить ключ записи в ассоциативном контейнере. –

+0

Возможно, это то, что Стив имел в виду: _ Основным свойством итераторов ассоциативных контейнеров является то, что они перебирают контейнеры в неубывающем порядке ключей, где невозвращение определяется путем сравнения, которое использовалось для . _ – dirkgently

ответ

3

Обычным является удаление, обновление и повторная установка. Практически все остальное по крайней мере временно нарушает первичный инвариант множества/мультимножества, что явно не очень хорошо.

0

Не обращайтесь к объектам по ссылке. Скопируйте их и снова вставьте их, если их ключ изменился. Вы можете использовать наблюдателя для автоматизации этого.

0

Если вы измените часть ключа сравнения объекта, сначала удалите элемент из набора, затем выполните модификацию, а затем добавьте его обратно в набор. Таким образом, вы не нарушаете инвариант множества, поскольку наборы просто не предназначены для изменения порядка изменения ключа.

1

Я до сих пор не могу найти ничего, что говорит это явно, но если вы измените ключ [*], то, например, ваш компаратор не удовлетворяет требованиям 25.3 (строгого слабого порядка):

компа индуцирует вполне определенное соотношение на классах эквивалентности определяется с помощью эквива

comp не вполне определенной связи, если она возвращает различные значения для одних и тех же входов в разное время.

В вашем случае я считаю, что это нормально, чтобы изменить поля MyClass, которые не участвуют в сравнении.

Интересно, что 23.1.2/2 говорит: «Каждый ассоциативный контейнер параметризуется на Ключ и отношение порядка сравнения, которое индуцирует строгий слабый порядок (25.3) на элементах Key». Я думаю, мы можем считать, что компаратор вызывает строгий слабый порядок на объектах , которые являются элементами контейнера, не обязательно на всех объектах типа Key. Например, если ключ является указателем, то я уверен, что писать компаратор, который разыгрывает его, хорошо, если вы не используете нулевой указатель в качестве ключа. По тем же соображениям, я надеюсь, что мы можем изменить ключ, который не находится в контейнере.

[*] под «изменить», я имею в виду все, что меняет результаты компаратора с этим ключом и другим ключом. В этом случае, конечно, вы действительно не модифицируете сам ключ (это всего лишь значение указателя), но это то, что я называю.