10 50 60 20 30 40 70 80
которая совпадает с выводом нижеследующей программы:
// splice.cpp: Сцепка, iinclude <iostream> iinclude <list> using namespace std;
int main()
{ list<int> L;
list<int>::iterator i, jl, j2, j; for (int k = 10; k <= 80; k += 10) { L.push_back(k);
j = L.end();
if (k == 20) jl = --j; else
if (k == 50) j2 = --j; else
if (k == 70) i = --j; }
L. spliced, L, jl, j2); copy(L.begin(), L.end(),
ostream_iterator<int>(cout, " ")); cout << endl; return 0; }
Обратим внимание на оператор
i = —-j;
и подобные ему в этой программе. Мы не можем заменить его на
i = j - 1;
потому что операторы «плюс» и «минус» не определены для двунаправленных итераторов (см. раздел 1.9). Здесь требуется использовать оператор —, так как итератор./ = L.end() ссылается на позицию после последнего элемента, который был добавлен с помощью pushjback. Вместо решения с тремя операторами if мы могли бы использовать алгоритм find, заменив довольно сложный цикл for, приведенный выше, на следующий фрагмент:
for (int k = 10; k <= 80; k += 10)
L.push_back(k); jl = find(L.begin(), L.end(), 20); j2 = find(L.begin(), L.end(), 50); i = find(L.begin(), L.end(), 70);
Данный фрагмент вполне приемлем для короткой последовательности, используемой в этой программе, но решение, приведенное в полном примере, более эффективно для очень длинных последовательностей.
Стоит вспомнить, что алгоритмы, такие как find, объявлены в заголовке algorithm, поэтому мы могли бы написать
iinclude <algorithm>
в начале нашей программы. Для ВС5 этот заголовок включается косвенным образом такими заголовками, как vector или list, поэтому мы опустили эту строчку, полагая, что другие современные версии STL ведут себя аналогично.
Функция-член remove класса list
Когда нам требуется удалить все элементы списка с заданным значением, решение в два этапа, использующее алгоритмы remove и erase, рассмотренное в разделе 1.13, является не самым эффективным. Гораздо лучше для этой цели подойдет функция-член remove, определенная для списков. Она объявлена в шаблонном классе list следующим образом:
void remove(const T& value);
Эта функция специфична для списков; она не определена как член для векторов и двусторонних очередей. Следующая программа показывает, что remove довольно проста в использовании:
<< назад вперед >>