Почему std:: set.insert() возвращает не-const-итератор, и все же я не могу его изменить?
Рассмотрим этот пример кода:
#include <set>
#include <string>
using namespace std;
set<string> string_set;
void foo(const string& a)
{
pair<set<string>::iterator, bool> insert_result = string_set.insert(a);
string& val = *(insert_result.first);
val += " - inserted";
}
Итак, исправление в сторону, например, не проверка успешной вставки и т.д., этот код выглядит так, что он должен позволять мне изменять строку после вставки, но компилятор (VS2010) запрещает разыменование итератора неконстантной строкой (мы переносимся с VS2005, который пропустил это без предупреждения).
Теперь я знаю, что это должно быть запрещено, так как это может сделать строку неповторимой, и я рад, что она работает таким образом, но в реальном мире это не совсем так ясно, как это, поскольку я хотите изменить неперемещаемый элемент данных, который не участвует в тестировании эквивалентности или заказе.
Что я хочу знать, как компилятор ЗНАЕТ, что мне не разрешено это делать, и как я могу узнать без ссылки на документацию (что вообще не упоминает об этом)?
Cheers,
Гай
Ответы
Ответ 1
Потому что согласно стандарту, модификации через
a set<>::iterator
не допускаются. Стандарт специально
позволяет set<>::iterator
и set<>::const_iterator
быть
такой же тип. И хотя это не требует от них того же
type, для этого требуется value_type
set<>::iterator
be const
.
Причиной этого, конечно же, является то, что любые модификации
значение может аннулировать инварианты std::set<>
.
Ответ 2
Из стандарта:
23.3.3
Множество является своего рода ассоциативным контейнер, который поддерживает уникальные ключи (содержит не более одного ключа значение) и обеспечивает быстрый поиск самих ключей. Набор классов поддерживает двунаправленные итераторы.
Это также из стандарта:
Определена реализация typedef итератор; // См. 23.1
Реальная реализация set:: iterator - это постоянный итератор, чтобы сохранить требование наличия уникальных ключей. В противном случае вы можете изменить значения в наборе на все те же значения.