Чтение онлайн

на главную - закладки

Жанры

Эффективное использование STL
Шрифт:

// и порядком сортировки, определяемым

// критерием StringPtrLess

// Вставить те же четыре строки

Теперь приведенный выше цикл будет работать именно так, как предполагалось (при условии, что ошибка была исправлена и вместо

*i
используется
**i
).

for (StringPtrSet::const_iterator i = ssp.begin;

 i != ssp.end; // Порядок вывода:

 ++i) // "Anteater", "Lemur",

 cout << **i << endl; // "Penguin", "Wombat"

Если

вы предпочитаете использовать алгоритм, напишите функцию, которая разыменовывает указатели
string*
перед выводом, а затем используйте ее в сочетании с
for_each
:

void print(const string *ps) // Вывести в cout объект,

{ // на который ссылается ps

 cout << *ps << endl;

}

for_each(ssp.begin, ssp.end, print); // Вызвать print для каждого

// элемента ssp

Существует более изощренное решение — обобщенный функтор разыменования, используемый с

transform
и
ostream_iterator
:

// Функтор получает T* и возвращает const T&

struct Dereference {

 template<typename T>

 const T& operator(const T* ptr) const {

return *ptr;

 }

};

transform(ssp.begin, ssp.end, // "Преобразовать" каждый

 ostream.iterator<string>(cout, "\n"), // элемент ssp посредством

 Dereference); // разыменования и записать

// результаты в cout

Впрочем, замена циклов алгоритмами будет подробно рассматриваться позднее, в совете 43. А сейчас речь идет о том, что при создании стандартного ассоциативного контейнера указателей следует помнить: содержимое контейнера будет сортироваться по значениям указателей. Вряд ли такой порядок сортировки вас устроит, поэтому почти всегда определяются классы-функторы, используемые в качестве типов сравнения.

Обратите внимание на термин «тип сравнения». Возможно, вас интересует, зачем возиться с созданием функтора вместо того, чтобы просто написать функцию сравнения для контейнера

set
? Например, так:

bool stringPtrLess(const string* ps1, // Предполагаемая функция сравнения

 const string* ps2) // для указателей string*,

{ // сортируемых по содержимому строки

 return *ps1 < *ps2;

}

set<string, stringPtrLess> ssp; // Попытка использования stringPtrLess

// в качестве функции сравнения ssp.

//
Не компилируется!!!

Проблема заключается в том, что каждый из трех параметров шаблона

set
должен быть типом. К сожалению,
stringPtrLess
— не тип, а функция, поэтому попытка задать
stringPtrLess
в качестве функции сравнения
set
не компилируется. Контейнеру
set
не нужна функция; ему нужен тип, на основании которого можно создатьфункцию.

Каждый раз, когда вы создаете ассоциативный контейнер указателей, помните о том, что вам, возможно, придется задать тип сравнения контейнера. В большинстве случаев тип сравнения сводится к разыменованию указателя и сравнению объектов, как это сделано в приведенном выше примере

StringPtrLess
. Шаблон для таких функторов сравнения стоит держать под рукой. Пример:

struct DereferenceLess {

 template <typename PtrType>

 bool operator(PtrType pT1, // Параметры передаются по значению.

PtrType рТ2) const // поскольку они должны быть

 { // указателями (или по крайней мере

return *рТ1 < *рТ2; // вести себя, как указатели)

 }

};

Данный шаблон снимает необходимость в написании таких классов, как

StringPtrLess
, поскольку вместо них можно использовать
DereferenceLess
:

set<string*, DereferenceLess> ssp; // Ведет себя так же, как

// set<string*, stringPtrLess>

И последнее замечание. Данный совет посвящен ассоциативным контейнерам указателей, но он в равной степени относится и к контейнерам объектов, которые ведут себя как указатели (например, умные указатели и итераторы). Если у вас имеется ассоциативный контейнер умных указателей или итераторов, подумайте, не стоит ли задать тип сравнения и для него. К счастью, решение, приведенное для указателей, работает и для объектов-аналогов. Если определение

DereferenceLess
подходит в качестве типа сравнения для ассоциативного контейнера
T*
, оно с большой вероятностью подойдет и для контейнеров итераторов и умных указателей на объекты
T
.

Совет 21. Следите за тем, чтобы функции сравнения возвращали false в случае равенства

Сейчас я покажу вам нечто любопытное. Создайте контейнер

set
с типом сравнения
less_equal
и вставьте в него число 10:

set<int, less_equal<int> > s; // Контейнер s сортируется по критерию "<="

s.insert(10); // Вставка числа 10

Теперь попробуйте вставить число 10 повторно:

s.insert(10);

Поделиться:
Популярные книги

Как я строил магическую империю 4

Зубов Константин
4. Как я строил магическую империю
Фантастика:
боевая фантастика
постапокалипсис
аниме
фантастика: прочее
фэнтези
5.00
рейтинг книги
Как я строил магическую империю 4

Безумный Макс. Поручик Империи

Ланцов Михаил Алексеевич
1. Безумный Макс
Фантастика:
героическая фантастика
альтернативная история
7.64
рейтинг книги
Безумный Макс. Поручик Империи

Попаданка 3

Ахминеева Нина
3. Двойная звезда
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Попаданка 3

Муж на сдачу

Зика Натаэль
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Муж на сдачу

Призыватель нулевого ранга. Том 3

Дубов Дмитрий
3. Эпоха Гардара
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Призыватель нулевого ранга. Том 3

На границе империй. Том 10. Часть 5

INDIGO
23. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 5

Адвокат

Константинов Андрей Дмитриевич
1. Бандитский Петербург
Детективы:
боевики
8.00
рейтинг книги
Адвокат

На границе империй. Том 7

INDIGO
7. Фортуна дама переменчивая
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
6.75
рейтинг книги
На границе империй. Том 7

Здравствуй, 1985-й

Иванов Дмитрий
2. Девяностые
Фантастика:
альтернативная история
5.25
рейтинг книги
Здравствуй, 1985-й

О, Путник!

Арбеков Александр Анатольевич
1. Квинтет. Миры
Фантастика:
социально-философская фантастика
5.00
рейтинг книги
О, Путник!

Чужбина

Седой Василий
2. Дворянская кровь
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Чужбина

Бестужев. Служба Государевой Безопасности. Книга четвертая

Измайлов Сергей
4. Граф Бестужев
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бестужев. Служба Государевой Безопасности. Книга четвертая

Локки 5. Потомок бога

Решетов Евгений Валерьевич
5. Локки
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Локки 5. Потомок бога

На границе империй. Том 10. Часть 4

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 4