Книги
чёрным по белому
Главное меню
Главная О нас Добавить материал Поиск по сайту Карта книг Карта сайта
Книги
Археология Архитектура Бизнес Биология Ветеринария Военная промышленность География Геология Гороскоп Дизайн Журналы Инженерия Информационные ресурсы Искусство История Компьютерная литература Криптология Кулинария Культура Лингвистика Математика Медицина Менеджмент Металлургия Минералогия Музыка Научная литература Нумизматика Образование Охота Педагогика Политика Промышленные производства Психология Путеводители Религия Рыбалка Садоводство Саморазвитие Семиотика Социология Спорт Столярное дело Строительство Техника Туризм Фантастика Физика Футурология Химия Художественная литература Экология Экономика Электроника Энергетика Этика Юриспруденция
Новые книги
Цуканов Б.И. "Время в психике человека" (Медицина)

Суворов С. "Танк Т-64. Первенец танков 2-го поколения " (Военная промышленность)

Нестеров В.А. "Основы проэктирования ракет класса воздух- воздух и авиационных катапульных установок для них" (Военная промышленность)

Фогль Б. "101 вопрос, который задала бы ваша кошка своему ветеринару если бы умела говорить" (Ветеринария)

Яблоков Н.П. "Криминалистика" (Юриспруденция)
Реклама

Эффективное использование STL. Библиотека программиста - Мейерс С.

Мейерс С. Эффективное использование STL. Библиотека программиста — Спб.: Питер , 2002. — 224 c.
ISBN 5-94723-382-7
Скачать (прямая ссылка): effektivnoeispolzovaniestlbibliote2002.djvu
Предыдущая << 1 .. 39 40 41 42 43 44 < 45 > 46 47 48 49 50 51 .. 114 >> Следующая

multiset и multimap, поскольку Стандарт не устанавливает никаких
ограничений на относительный порядок следования эквивалентных значений
(multiset) или ключей (multimap). Или нам следует настоять на
детерминированном порядке содержимого s и проигнорировать вторую попытку
вставки (для строки "persephone")? А если будет выбран этот вариант, что
произойдет при выполнении следующей команды:
if (s.findC'persephdne") != s.endO)... // Каким будет результат проверки?
Функция find использует проверку равенства, но если проигнорировать
второй вызов insert для сохранения детерминированного порядка элементов
s, проверка даст отрицательный результат - хотя строка "persephone" была
отвергнута как дубликат!
Мораль: используя одну функцию сравнения и принимая решение о
"совпадении" двух значений на основании их эквивалентности, мы избегаем
многочисленных затруднений, возникающих при использовании двух функций
сравнения. Поначалу такой подход выглядит несколько странно (особенно
когда вы видите, что внутренняя и внешняя версии find возвращают разные
результаты), но в перспективе он избавляет от всевозможных затруднений,
возникающих при смешанном использовании равенства и эквивалентности в
стандартных ассоциативных контейнерах.
Но стоит отойти от сортированных ассоциативных контейнеров, как ситуация
изменяется, и проблему равенства и эквивалентности приходится решать
заново. Существуют две общепринятые реализации для нестандартных (но
широко распространенных) ассоциативных контейнеров на базе хэш-таблиц.
Одна реализация основана на равенстве, а другая - на эквивалентности. В
совете 25 приводится дополнительная информация об этих контейнерах и тех
принципах, на которых они основаны.
Совет 20. Определите тип сравнения для ассоциативного контейнера,
содержащего указатели
Предположим, у нас имеется контейнер set, содержащий указатели stri ng*,
и мы пытаемся включить в него несколько новых элементов:
set<string*> ssp: // ssp = "set of string ptrs"
ssp.i nsert(new stri ng("Anteater"));
ssp.insert(new string("Wombat")):
ssp.insert(new stri ng("Lemur"));
ssp.i nsert(new stri ng("Pengui n")):
88 Глава 3 • Ассоциативные контейнеры
Следующий фрагмент выводит содержимое set. Предполагается, что строки
будут выведены в алфавитном порядке - ведь содержимое контейнеров set
автоматически сортируется!
for (set<string*>; ;const_iterator i - ssp.beginO: // Предполагаемый
Однако на практике ничего похожего не происходит. Вместо строк выводятся
четыре шестнадцатеричных числа - значения указателей. Поскольку в
контейнере set хранятся указатели, *1 является не строкой, а указателем
на строку. Пусть этот урок напоминает, чтобы вы следовали рекомендациям
совета 43 и избегали написания собственных циклов. Использование
алгоритма сору:
copy(ssp.begin().ssp.endO, // Скопировать строки.
ostream_iterator<string>(cout."\п")): II содержащиеся в ssp. в cout
// (не компилируется!)
не только делает программу более компактной, но и помогает быстрее
обнаружить ошибку, поскольку вызов сору не компилируется. Итератор
ostream_iterator должен знать тип выводимого объекта, поэтому когда
компилятор обнаруживает расхождение между заданным в параметре шаблона
типом string и типом объекта, хранящегося в ssp (string*), он выдает
ошибку. Еще один довод в пользу сильной типизации...
Если заменить *1 в цикле на **i, возможно, вы получите нужный результат -
но скорее всего, этого не произойдет. Да, строки будут выведены, но
вероятность их следования в алфавитном порядке равна всего 1 /24.
Контейнер ssp хранит свои элементы в отсортированном виде, однако он
содержит указатели, поэтому сортироваться будут значения указателей, а не
строки. Существует 24 возможных перестановки для четырех указателей, то
есть 24 разных последовательности, из которых лишь одна отсортирована в
алфавитном порядке1.
Подходя к решению этой проблемы, нелишне вспомнить, что объявление
set<string*> ssp:
представляет собой сокращенную запись для объявления
set<string*.1ess<stnng*> > ssp;
Строго говоря, это сокращенная запись для объявления
set<string*.less<string*>.a11ocator<stnng*> > ssp;
но в контексте данного совета распределители памяти несущественны.
Если вы хотите сохранить указатели stri ng* в контейнере set так, чтобы
их порядок определялся значениями строк, стандартный функтор сравнения 1
ess<stri ng*> вам не подойдет. Вместо этого необходимо написать
собственный функтор сравнения, который получает указатели string* и
упорядочивает их по содержимому строк, на которые они ссылаются. Пример:
1 Строго говоря, не все 24 перестановки равновероятны, так что
вероятность 1/24 не совсем точна. Тем не менее, остается бесспорный факт:
а/ществуют 24 разные перестановки, и вы можете получить любую из них.
i !- ssp.endO; ++i) cout"*i"endl:
// порядок вывода;
11 "Anteater". "Lemur", // "Penguin", "Wombat"
Совет 20 89
struct StringPtrLess: public binary_function<const string*. // Базовый
Предыдущая << 1 .. 39 40 41 42 43 44 < 45 > 46 47 48 49 50 51 .. 114 >> Следующая