Forward_list


Контейнер forward_list представляет односвязный список. Для его использования необходимо подключить заголовочный файл forward_list.

Создание односвязного списка:

1
2
3
4
5
6
7
8
std::forward_list<int> list1; // пустой список
std::forward_list<int> list2(5); // list2 имеет 5 элементов, каждый из которых имеет значение по умолчанию
std::forward_list<int> list3(5, 2); // list3 состоит из 5 чисел, каждое число равно 2
std::forward_list<int> list4{ 1, 2, 4, 5 }; // list4 состоит из чисел 1, 2, 4, 5
std::forward_list<int> list5 = { 1, 2, 3, 4, 5 }; // list5 состоит из чисел 1, 2, 3, 4, 5
std::forward_list<int> list6(list4); // list6 - копия списка list4
std::forward_list<int> list7 = list4; // list7 - копия списка list4
std::forward_list<int> list8({ 1, 2, 3, 4, 5, 6 }); // list8 состоит из чисел 1, 2, 3, 4, 5, 6
Получение элементов
Напрямую в списке forward_list можно получить только первый элемент. Для этого применяется функция front(). Для перебора элементов также можно использовать цикл:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <forward_list>

int main()
{
std::forward_list<int> numbers = { 1, 2, 3, 4, 5 };

int first = numbers.front(); // 1

for (int n : numbers)
std::cout << n << "\t";
std::cout << std::endl;
return 0;
}
Также для перебора и получения элементов можно использовать итераторы. Причем класс forward_list добавляет ряд дополнительных функций для получения итераторов: before_begin() и cbefore_begin(). Обе функции возвращают итератор (вторая функция возвращает константный итератор const_iterator) на несуществующий элемент непосредственно перед началом списка. К значению по этому итератору обратиться нельзя.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <forward_list>

int main()
{
std::forward_list<int> numbers = { 1, 2, 3, 4, 5 };

auto prev = numbers.before_begin();

auto current = numbers.begin();
auto end = numbers.end();
while (current != end)
{
std::cout << *current << "\t";
current++;
}
std::cout << std::endl;

return 0;
}
Размер списка
По умолчанию класс forward_list не определяет никаких функций, которые позволяют получить размер контейнера. В этом классе только функция max_size(), которая позволяет получить масимальный размер контейнера.

Функция empty() позволяет узнать, пуст ли список. Если он пуст, то функция возвращает значение true, иначе возвращается значение false:

1
2
3
4
5
std::forward_list<int> numbers = { 1, 2, 3, 4, 5 };
if (numbers.empty())
std::cout << "The forward_list is empty" << std::endl;
else
std::cout << "The forward_list is not empty" << std::endl;
Для изменения размера контейнера можно использовать функцию resize(), которая имеет две формы:

resize(n): оставляет в списке n первых элементов. Если список содержит больше элементов, то он усекается до первых n элементов. Если размер списка меньше n, то добавляются недостающие элементы и инициализируются значением по умолчанию

resize(n, value): также оставляет в списке n первых элементов. Если размер списка меньше n, то добавляются недостающие элементы со значением value

Использование функции:

1
2
3
4
std::forward_list<int> numbers = { 1, 2, 3, 4, 5, 6 };
numbers.resize(4); // оставляем первые четыре элемента - numbers = {1, 2, 3, 4}

numbers.resize(6, 8); // numbers = {1, 2, 3, 4, 8, 8}
Изменение элементов списка
Функция assign() позволяет заменить все элементы списка определенным набором. Она имеет следующие формы:

assign(il): заменяет содержимое контейнера элементами из списка инициализации il

assign(n, value): заменяет содержимое контейнера n элементами, которые имеют значение value

assign(begin, end): заменяет содержимое контейнера элементами из диапазона, на начало и конец которого указывают итераторы begin и end

Применение функции:

1
2
3
4
5
6
7
8
9
10
std::forward_list<int> numbers = { 1, 2, 3, 4, 5 };

numbers.assign({ 21, 22, 23, 24, 25 }); // numbers = { 21, 22, 23, 24, 25 }

numbers.assign(4, 3); // numbers = {3, 3, 3, 3}

std::list<int> values = { 6, 7, 8, 9, 10, 11 };
auto start = ++values.begin(); // итератор указывает на второй элемент из values
auto end = values.end();
numbers.assign(start, end); // numbers = { 7, 8, 9, 10, 11 }
Функция swap() обменивает значениями два списка:

1
2
3
4
5
std::forward_list<int> list1 = { 1, 2, 3, 4, 5 };
std::forward_list<int> list2 = { 6, 7, 8, 9};
list1.swap(list2);
// list1 = { 6, 7, 8, 9};
// list2 = { 1, 2, 3, 4, 5 };
Добавление элементов
Для добавления элементов в forward_list применяются следующие функции:

push_front(val): добавляет объект val в начало списка

emplace_front(val): добавляет объект val в начало списка

emplace_after(p, val): вставляет объект val после элемента, на который указывает итератор p. Возвращает итератор на вставленный элемент. Если p представляет итератор на позицию после конца списка, то результат неопределен.

insert_after(p, val): вставляет объект val после элемента, на который указывает итератор p. Возвращает итератор на вставленный элемент.

insert_after(p, n, val): вставляет n объектов val после элемента, на который указывает итератор p. Возвращает итератор на последний вставленный элемент.

insert_after(p, begin, end): вставляет после элемента, на который указывает итератор p, набор объектов из другого контейнера, начало и конец которого определяется итераторами begin и end. Возвращает итератор на последний вставленный элемент.

insert_after(p, il): вставляет после элемента, на который указывает итератор p, список инициализации il. Возвращает итератор на последний вставленный элемент.

Применение функций:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <list>
#include <forward_list>

int main()
{
std::forward_list<int> numbers = { 7, 8 };
numbers.push_front(6); // добавляем в начало число 6
// numbers = { 6, 7, 8 }

numbers.emplace_front(-3); // добавляем в начало число -3
// numbers = { -3, 6, 7, 8 }

auto iter = numbers.begin();
iter = numbers.emplace_after(iter, -2); // добавляем после итератора число -2
// numbers = { -3, -2, 6, 7, 8 }

iter = numbers.insert_after(iter, -1);
// numbers = { -3, -2, -1, 6, 7, 8 }

iter = numbers.insert_after(iter, 3, 0); // добавляем три нуля
// numbers = { -3, -2, -1, 0, 0, 0, 6, 7, 8 }

std::list<int> values = { 1, 2, 3 };
iter = numbers.insert_after(iter, values.begin(), values.end()); // добавляем все элементы из values
// numbers = { -3, -2, -1, 0, 0, 0, 1, 2, 3, 6, 7, 8 }

numbers.insert_after(iter, { 4, 5 }); // добавляем список { 4, 5 }
// numbers = { -3, -2, -1, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8 }

for(int n : numbers)
std::cout << n << "\t";
std::cout << std::endl;

return 0;
}
Удаление элементов
Чтобы удалить элемент из контейнера forward_list можно использовать следующие функции:

clear(): удаляет все элементы

pop_front(): удаляет первый элемент

erase_after(p): удаляет элемент после элемента, на который указывает итератор p. Возвращает итератор на элемент после удаленного

erase_after(begin, end): удаляет диапазон элементов, на начало и конец которого указывают соответственно итераторы begin и end. Возвращает итератор на элемент после последнего удаленного

Использование функций:

1
2
3
4
5
6
7
8
9
10
11
std::forward_list<int> numbers = { 1, 2, 3, 4, 5, 6, 7};

numbers.pop_front();
// numbers = { 2, 3, 4, 5, 6, 7};

auto iter = numbers.erase_after(numbers.begin());
// numbers = { 2, 4, 5, 6, 7 };
// iter указывает на элемент 4

numbers.erase_after(iter, numbers.end());
// numbers = { 2, 4 };