![]() |
|
Модераторы: bsa |
![]()
|
|
| zim22 |
|
|||
|
depict1 ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2682 Регистрация: 15.1.2009 Где: Украина Репутация: 29 Всего: 69 |
Код, указанный ниже, отлично работает и меняет по итератору значение ключа в set.
Но в книжке (Язык программирования С++. Вводный курс / С++ Primer, Fourth Edition) написано, что ключи в set константны и соответственно не поддаются изменению. Может у меня компилятор свихнулся? Цитата из книжки: "Подобно тому, как в элементе карты нельзя изменить ключ, ключи набора (set) также константны. Если существует итератор на элемент набора, то все, что с ним можно сделать, - это прочитать ключ, а запись при помощи итератора невозможна. То же самое в англ.версии книжки: "Just as we cannot change the key part of a map element, the keys in a set are also const. If we have an iterator to an element of the set, all we can do is read it; we cannot write through it"
|
|||
|
||||
| pan2004 |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 357 Регистрация: 28.7.2007 Репутация: 2 Всего: 9 |
zim22, ну я как-то не вижу в приведенном тобой примере, чтобы ты ключи менял.
Судя по всему, ты спутал понятия ключ-значение(значение неконстантным итератором изменить естественно можно, на то он и неконстантный) |
|||
|
||||
| zim22 |
|
|||
|
depict1 ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2682 Регистрация: 15.1.2009 Где: Украина Репутация: 29 Всего: 69 |
pan2004, в моём коде были ещё комментарии, но я их удалил, в них указано, что мы оперируем именно ключами, а не значениями:
Т.е. мы всё-таки оперирум с ключами, а не со значениями. Т.к. контейнер set в MSDN описывается как содержащий только ключи, а не значения: "An STL set is: An associative container, which a variable size container that supports the efficient retrieval of element values based on an associated key value. Further, it is a simple associative container because its element values are its key values." |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
|
|||
|
||||
| azesmcar |
|
||||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
Жизнь такого не говорит!!! Это Visual Studio упорно так твердит потому что по инерции продолжает не соответствовать стандарту. На GCC попробуй, результат совершенно другой. bsa Да, вести себя они должны одинаково, но если для map или set изменить ключ он должен перестроить все дерево (я честно не пробовал, но сомневаюсь что студио это делает). Я сталкивался с тем же самым..сам был удивлен, как такое возможно, почитал стандарт, попробовал на GCC - все встало на свои места
В 2008 студии уже исправили Это сообщение отредактировал(а) azesmcar - 3.3.2009, 07:54 |
||||
|
|||||
| vinter |
|
||||||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 8 Всего: 56 |
а ты стандарт открыл, прежде чем сказать ерунду? обьявления из стандарта.
т.е в стандарте по этому поводу ничего ясного нет. Студия поступает вполне корректно. Добавлено через 2 минуты и 34 секунды zim22, посмотри книгу Саттера, "Решение сложны задач на С++". Задача 1.15 |
||||||
|
|||||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
vinter, красивая функция, но какое отношение имеет твоя функция find к тому что я написал?
Стандарт неохота открывать, да и не нужно читать стандарт чтобы узнать что менять ключь сета нельзя. А то что студия не соответствует стандарту давно известный факт, насчет 2008 не ручаюсь, но ранние версии точно. Полно проблем с шаблонами и STL. |
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
Вот вам и стандарт, открыл все таки, и вам бы не помешало перед тем как написанное другими ерундой называть.
|
|||
|
||||
| vinter |
|
||||
![]() Explorer ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2735 Регистрация: 1.4.2006 Где: Н.Новгород Репутация: 8 Всего: 56 |
ты отвечал на вопрос zim22, у которого в коде используется set и find.
можно его менять. Читай стандарт, это не запрещается. А что не запрещено, то разрешено. обычно в таких случаях приводят аргументы, иначе твои слова остаются пустословием. отлично, а map nne причем? Еще раз название темы перечитай. |
||||
|
|||||
| azesmcar |
|
||||||||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
но вопрос был не про find а про изменение ключа. Он и std::string использовал в своем примере, что нам теперь про std::string разговаривать?
я уже привел цитату из стандарта и из журнала C++ Report. Этого мало?
Если тебе нужны аргументы - это отдельная тема которая не подлежит обсуждению в этом топике, скажу только что в шестой студии не работала частичная специализация а конструктор std::exception у них до сих пор принимает параметр std::string, хотя в стандарте описан иной интерфейс класса std::exception - в результате до фига непереносимого кода, потому что люди пишут throw std::exception("error"). В приоритетах выборки первичного шаблона были некоторые проблемы и (уже не помню) какой студии. Если хочешь открой отдельную тему пообсуждаем.
а map притом что без разницы. Просто для удобства привел пример на map, чтобы показать что ключь нельзя менять а значение можно. Добавлено через 2 минуты и 25 секунд ассоциативные контейнеры работают по одному принципу - построение дерева, если изменить значение - дерево станет недееспособным, потому без разницы. |
||||||||
|
|||||||||
| zim22 |
|
|||
|
depict1 ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2682 Регистрация: 15.1.2009 Где: Украина Репутация: 29 Всего: 69 |
понял, что ключи мне пока лучше не изменять, а удалять и создавать заново, чтобы не нарушилась внутренняя структура set. |
|||
|
||||
| azesmcar |
|
|||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
Так...нашел.
Значит я правильно помнил, в 2008 тоже работало..
получаем в результате 1 2 1 4 насколько соответствует СТАНДАРТУ то что в ассоциативном контейнере set может быть два одинаковых ключа - думайте сами. Или мне привезти цитату из стандарта что set долже иметь уникальные ключи? |
|||
|
||||
| zim22 |
|
||||
|
depict1 ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2682 Регистрация: 15.1.2009 Где: Украина Репутация: 29 Всего: 69 |
всё верно. про изменение ключа в set, но не в map. Т.к. в map ключи константны. но на момент написания кода я не знал, как получить доступ к ключу. поэтому и использовал функцию find. это не принципиально важно. можно использовать вместо find итератор на начало:
В этой цитате говорится, что менять ключ нельзя, т.к. это может изменить относительную позицию в контейнере. Но если менять ключ так, чтобы его относительная позиция сохранялась, то изменять значения ключей можно. как и в map, так и в set. есть разница в том, что Саттер |
||||
|
|||||
| azesmcar |
|
||||||
![]() uploading... ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6291 Регистрация: 12.11.2004 Где: Армения Репутация: 52 Всего: 211 |
я знаю что пишет Саттер, и видел что в стандарте ключь сета не описан как константный. Но это еще ничего не значит, стандарт тоже не идеален, потому существуют книги, журналы и тому подобное, в статье C++ report явно написано что ключь должен быть константным для любого ассоциативного контейнера. И Саттер тоже не мало запрещал делать то что позволяет стандарт. А почему студия не соответствует стандарту, смотрите пример. Добавлено через 2 минуты и 20 секунд
где это такое говорится?
по моему ясно написано. |
||||||
|
|||||||
| zim22 |
|
||||||
|
depict1 ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2682 Регистрация: 15.1.2009 Где: Украина Репутация: 29 Всего: 69 |
Возможно я не правильно перевёл Как только ключ был вставлен в контейнер, его лучше не изменять такими способами, которые меняли бы его относительную позицию в контейнере. Из этого я делаю вывод, что если при изменении ключа его относительная позиция не изменится - то изменять его можно. Добавлено через 5 минут и 7 секунд В этом примере Вы умышленно изменили относительную позицию элемента в контейнере. Тем самым Вы сами берёте ответственность за порчу его структуры. Хотя и MSVC 2008 позволяет это делать
я думаю в таких случаях необходимо явно указывать, что мы будем изменять ключ. т.е. с помощью const_cast приведения
Это сообщение отредактировал(а) zim22 - 3.3.2009, 10:01 |
||||||
|
|||||||
![]()
|
| Правила форума "C/C++: Для новичков" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
| 1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |