LINUX.ORG.RU

Как сделать итератор от set не константным по умолчанию?

 , ,


0

1

Можно ли что-либо сделать с итератором std::set что бы можно было итерировать значения без конст-признака по умолчанию?


class Compare {
   bool operator()(const MyClass& v1, const MyClass& v2) const {
       return v1.constKey() < v2.constKey();
   }
};

std::set<MyClass,Compare> mySet;

...
for (MyClass& item: mySet) // <- error here
   ...;
Или без оберток не обойтись?

Ответ на: комментарий от ox55ff

Защита от выстрела в ногу. Вдруг после модификации объекта у него ключ поменяется?
Менять значение inplace ты не можешь потому что тогда set сломается.

А для кого я специально написал реализацию класса Compare? Конечно же для КэПов. Ой, теперь и я КэП..

victor79
() автор топика
Последнее исправление: victor79 (всего исправлений: 1)
Ответ на: комментарий от victor79

Спасибо, Кэп, я видел. Но какое это имеет отношение к твоему вопросу?

std::set - дерево (как правило). При вставке в контейнер, элемент будет расположен в соответствующем месте согласно ключу. Потом ты через мутабельный итератор меняешь содержимое элемента, что может привести к изменению ключа, и теперь элемент находится не в том месте дерева –> std::set развалился.

Контейнер не знает, что ключ поменялся и не может перестроить дерево. Ты там видел коллбеки для для информирования контейнера, что ключ поменялся? Я нет. Потому что их нет.

Ты хочешь неправильного.

ox55ff ★★★★★
()
Ответ на: комментарий от victor79

А для кого я специально написал реализацию класса Compare? Конечно же для КэПов. Ой, теперь и я КэП..

А при чём тут реализация Compare? Имея мутабельный итератор ты можешь легально изменить состояние класса так что результат сравнения изменится, а следовательно нарушатся инварианты set и начнётся UB.

slovazap ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.