// Fill up intLst...

intLst.remove_if(even); // Удаляет все элементы, для которых even(*p)

                        // != false

Если предикаты более сложные, то попробуйте использовать какие-то из функторов из <functional>. Например, если требуется удалить элементы, которые больше определенного значения, используйте в remove_if объединение из greater (из <algorithm>) и bind2nd.

intLst.remove_if(std::bind2nd(std::greater<int>(), 2));

В результате этого из intLst будут удалены все значения, которые больше 2. Эта запись несколько необычна, но ничего сложного в ней нет. bind2nd принимает два аргумента — объект функции (назовем ее f) и значение (v) — и возвращает объект функции, который принимает один аргумент (arg) и вызывает f(arg, v) . bind2nd — это простой способ делать подобные вещи без необходимости писать набор небольших функций.

list — это хорошая альтернатива вектору, когда требуется стандартный последовательный контейнер. Другое внутреннее представление list позволяет ему обеспечить другой уровень сложности многих стандартных операций с последовательностями и несколько дополнительных операций.

Смотри также

Рецепт 6.1.

6.6. Отображение строк на другие объекты

Проблема

Имеются объекты, которые требуется сохранить в памяти, и вы хотите хранить их по ключам типа string. Требуется иметь возможность быстро добавлять, удалять и получать элементы (с, как максимум, логарифмической сложностью).

Решение

Для отображения ключей (string) на значения (любой тип, который подчиняется семантике значений) используйте стандартный контейнер map, объявленный в <map>. Пример 6.6 показывает, как это делается.

Пример 6.6. Создание отображения строк

#include <iostream>

#include <map>

#include <string>

using namespace std;

int main() {

 map<string, string> strMap;

 strMap['Monday'] = 'Montag';

 strMap['Tuesday'] = 'Dienstag';

 strMap['Wednesday'] = 'Mittwoch';

 strMap['Thursday'] = 'Donnerstag';

 strMap['Friday'] = 'Freitag';

 strMap['Saturday'] = 'Samstag';

 // strMap.insert(make_pair('Sunday', 'Sonntag'));

 strMap.insert(pair<string, string>('Sunday', 'Sonntag'));

 for(map<string, string>::iterator p = strMap.begin();

  p != strMap.end(); ++p) {

  cout << 'English: ' << p->first

   << German: ' << p->second << endl;

 }

 cout << endl;

 strMap.erase(strMap.find('Tuesday'));

 for (map<string, string>::iterator p = strMap.begin();

  p ! = strMap.end(); ++p) {

  cout << 'English: ' << p->first

   << ', German: ' << p->second << endl;

 }

}

Обсуждение

map — это ассоциативный контейнер, который отображает ключи на значения, предоставляет логарифмическую сложность вставки и поиска и постоянную сложность удаления одного элемента. Обычно разработчики используют отображение для хранения объектов по их ключам типа string. Именно это делает пример 6.6. В этом случае отображаемый тип является строкой, но он может быть почти чем угодно.

Отображение объявляется вот так.

map<typename Key, // Тип ключа

 typename Value,  // Тип значения

 typename LessThanFun = std::less<Key>, // Функция/функтор,

                                        // используемые для сортировки

 typename Alloc = std::allocator<Key> > // Распределитель памяти

Key и Value — это типы ключа и связанного значения, которые хранятся в отображении. LessThanFun — это функция или функтор, который принимает два аргумента и возвращает истину, если первый меньше, чем второй. По умолчанию используется стандартный функтор less. Alloc — это распределитель памяти, и по умолчанию используется стандартный.

Использование map довольно просто. Объявите тип ключа и значения вот так.

map<string, string> strMan;

В результате будет создан map, в котором и ключ, и значение имеют тип string. С помощью operator[] поместите в отображение объекты, что интуитивно и легко читаемо.

strMap['Monday'] = Montag';

strMap['Tuesday'] = 'Dienstag';

strMap['Wednesday'] = 'Mittwoch'; // ...

В результате в map будут вставлены элементы с индексом (например, 'Monday') в качестве ключа и правым операндом в качестве значения. Они хранятся в порядке, определяемом параметром шаблона LessThanFun, и если он не указан, то map использует std::less<Key>.

Чтобы получить значения из map, используйте operator[] в правой части присвоения, как здесь.

wedInGerman = strMap['Wednesday'];

В манере всех стандартных контейнеров значение, связанное с ключом 'Wednesday', с помощью operator= копируется в объект wedInGerman.

operator[] — это удобный способ вставки или обновления элементов или получения значений из map, но он имеет побочный эффект, который может оказаться неожиданным. Строго говоря,

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату