// 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 показывает, как это делается.
#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, но он имеет побочный эффект, который может оказаться неожиданным. Строго говоря,