Точный ответ зависит от платформы, но, как правило, «ключ» (материал, который вы кладете в набор или первый тип карты), считается «неизменным». Проще говоря, это не должно быть изменено, и нет такой вещи, как автоматическая повторная вставка.
Точнее, переменные-члены , используемые для сравнения ключа, изменять нельзя.
Компилятор Windows vc довольно гибкий (протестирован с VC8), и этот код компилируется:
// creation
std::set<int> toto;
toto.insert(4);
toto.insert(40);
toto.insert(25);
// bad modif
(*toto.begin())=100;
// output
for(std::set<int>::iterator it = toto.begin(); it != toto.end(); ++it)
{
std::cout<<*it<<" ";
}
std::cout<<std::endl;
Вывод 100 25 40 , который явно не отсортирован ... Плохо ...
Тем не менее, такое поведение полезно, когда вы хотите изменить данные, не участвующие в операторе <</em>. Но вам лучше знать, что вы делаете: это цена, которую вы получаете за слишком гибкий подход.
Некоторые могут предпочесть поведение gcc (протестировано с 3.4.4), которое выдает ошибку «назначение местоположения только для чтения». Вы можете обойти это с const_cast:
const_cast<int&>(*toto.begin())=100;
Это теперь компилируется и на gcc, тот же вывод: 100 25 40 .
Но, по крайней мере, это, вероятно, заставит вас задуматься о том, что происходит, а затем перейдите к переполнению стека и увидите этот поток: -)