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

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

Жанры

Эффективное использование 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);

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

Ученичество. Книга 1

Понарошку Евгений
1. Государственный маг
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Ученичество. Книга 1

Идеальный мир для Лекаря 7

Сапфир Олег
7. Лекарь
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 7

Обыкновенные ведьмы средней полосы

Шах Ольга
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Обыкновенные ведьмы средней полосы

Треск штанов

Ланцов Михаил Алексеевич
6. Сын Петра
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Треск штанов

Медиум

Злобин Михаил
1. О чем молчат могилы
Фантастика:
фэнтези
7.90
рейтинг книги
Медиум

"Фантастика 2023-123". Компиляция. Книги 1-25

Харников Александр Петрович
Фантастика 2023. Компиляция
Фантастика:
боевая фантастика
альтернативная история
5.00
рейтинг книги
Фантастика 2023-123. Компиляция. Книги 1-25

Гром над Тверью

Машуков Тимур
1. Гром над миром
Фантастика:
боевая фантастика
5.89
рейтинг книги
Гром над Тверью

Идеальный мир для Лекаря 11

Сапфир Олег
11. Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 11

Совок

Агарев Вадим
1. Совок
Фантастика:
фэнтези
детективная фантастика
попаданцы
8.13
рейтинг книги
Совок

Табу на вожделение. Мечта профессора

Сладкова Людмила Викторовна
4. Яд первой любви
Любовные романы:
современные любовные романы
5.58
рейтинг книги
Табу на вожделение. Мечта профессора

Сонный лекарь 4

Голд Джон
4. Не вывожу
Фантастика:
альтернативная история
аниме
5.00
рейтинг книги
Сонный лекарь 4

Огненный князь 4

Машуков Тимур
4. Багряный восход
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Огненный князь 4

Войны Наследников

Тарс Элиан
9. Десять Принцев Российской Империи
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Войны Наследников

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

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